Skip to content

Commit

Permalink
add vif using local interface index instead of IP
Browse files Browse the repository at this point in the history
When routing daemon wants to enable forwarding of multicast traffic it
performs something like:

       struct vifctl vc = {
               .vifc_vifi  = 1,
               .vifc_flags = 0,
               .vifc_threshold = 1,
               .vifc_rate_limit = 0,
               .vifc_lcl_addr = ip, /* <--- ip address of physical
interface, e.g. eth0 */
               .vifc_rmt_addr.s_addr = htonl(INADDR_ANY),
         };
       setsockopt(fd, IPPROTO_IP, MRT_ADD_VIF, &vc, sizeof(vc));

This leads (in the kernel) to calling  vif_add() function call which
search the (physical) device using assigned IP address:
       dev = ip_dev_find(net, vifc->vifc_lcl_addr.s_addr);

The current API (struct vifctl) does not allow to specify an
interface other way than using it's IP, and if there are more than a
single interface with specified IP only the first one will be found.

The attached patch (against 2.6.30.4) allows to specify an interface
by its index, instead of IP address:

       struct vifctl vc = {
               .vifc_vifi  = 1,
               .vifc_flags = VIFF_USE_IFINDEX,   /* NEW */
               .vifc_threshold = 1,
               .vifc_rate_limit = 0,
               .vifc_lcl_ifindex = if_nametoindex("eth0"),   /* NEW */
               .vifc_rmt_addr.s_addr = htonl(INADDR_ANY),
         };
       setsockopt(fd, IPPROTO_IP, MRT_ADD_VIF, &vc, sizeof(vc));

Signed-off-by: Ilia K. <mail4ilia@gmail.com>

=== modified file 'include/linux/mroute.h'
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
lazyuser authored and davem330 committed Oct 7, 2009
1 parent 7bb5fdc commit ee5e81f
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 5 deletions.
13 changes: 9 additions & 4 deletions include/linux/mroute.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,18 @@ struct vifctl {
unsigned char vifc_flags; /* VIFF_ flags */
unsigned char vifc_threshold; /* ttl limit */
unsigned int vifc_rate_limit; /* Rate limiter values (NI) */
struct in_addr vifc_lcl_addr; /* Our address */
union {
struct in_addr vifc_lcl_addr; /* Local interface address */
int vifc_lcl_ifindex; /* Local interface index */
};
struct in_addr vifc_rmt_addr; /* IPIP tunnel addr */
};

#define VIFF_TUNNEL 0x1 /* IPIP tunnel */
#define VIFF_SRCRT 0x2 /* NI */
#define VIFF_REGISTER 0x4 /* register vif */
#define VIFF_TUNNEL 0x1 /* IPIP tunnel */
#define VIFF_SRCRT 0x2 /* NI */
#define VIFF_REGISTER 0x4 /* register vif */
#define VIFF_USE_IFINDEX 0x8 /* use vifc_lcl_ifindex instead of
vifc_lcl_addr to find an interface */

/*
* Cache manipulation structures for mrouted and PIMd
Expand Down
12 changes: 11 additions & 1 deletion net/ipv4/ipmr.c
Original file line number Diff line number Diff line change
Expand Up @@ -469,8 +469,18 @@ static int vif_add(struct net *net, struct vifctl *vifc, int mrtsock)
return err;
}
break;

case VIFF_USE_IFINDEX:
case 0:
dev = ip_dev_find(net, vifc->vifc_lcl_addr.s_addr);
if (vifc->vifc_flags == VIFF_USE_IFINDEX) {
dev = dev_get_by_index(net, vifc->vifc_lcl_ifindex);
if (dev && dev->ip_ptr == NULL) {
dev_put(dev);
return -EADDRNOTAVAIL;
}
} else
dev = ip_dev_find(net, vifc->vifc_lcl_addr.s_addr);

if (!dev)
return -EADDRNOTAVAIL;
err = dev_set_allmulti(dev, 1);
Expand Down

0 comments on commit ee5e81f

Please sign in to comment.