mirror of
https://github.com/torvalds/linux.git
synced 2024-11-28 07:01:32 +00:00
Merge branch 'Allow-more-than-255-IPv4-multicast-interfaces'
Paul Davey says: ==================== Allow more than 255 IPv4 multicast interfaces Currently it is not possible to use more than 255 multicast interfaces for IPv4 due to the format of the igmpmsg header which only has 8 bits available for the VIF ID. There is space available in the igmpmsg header to store the full VIF ID in the form of an unused byte following the VIF ID field. There is also enough space for the full VIF ID in the Netlink cache notifications, however the value is currently taken directly from the igmpmsg header and has thus already been truncated. Adding the high byte of the VIF ID into the unused3 byte of igmpmsg allows use of more than 255 IPv4 multicast interfaces. The full VIF ID is also available in the Netlink notification by assembling it from both bytes from the igmpmsg. Additionally this reveals a deficiency in the Netlink cache report notifications, they lack any means for differentiating cache reports relating to different multicast routing tables. This is easily resolved by adding the multicast route table ID to the cache reports. changes in v2: - Added high byte of VIF ID to igmpmsg struct replacing unused3 member. - Assemble VIF ID in Netlink notification from both bytes in igmpmsg header. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
8c5c49a6a0
@ -113,8 +113,8 @@ struct igmpmsg {
|
||||
__u32 unused1,unused2;
|
||||
unsigned char im_msgtype; /* What is this */
|
||||
unsigned char im_mbz; /* Must be zero */
|
||||
unsigned char im_vif; /* Interface (this ought to be a vifi_t!) */
|
||||
unsigned char unused3;
|
||||
unsigned char im_vif; /* Low 8 bits of Interface */
|
||||
unsigned char im_vif_hi; /* High 8 bits of Interface */
|
||||
struct in_addr im_src,im_dst;
|
||||
};
|
||||
|
||||
@ -169,6 +169,7 @@ enum {
|
||||
IPMRA_CREPORT_SRC_ADDR,
|
||||
IPMRA_CREPORT_DST_ADDR,
|
||||
IPMRA_CREPORT_PKT,
|
||||
IPMRA_CREPORT_TABLE,
|
||||
__IPMRA_CREPORT_MAX
|
||||
};
|
||||
#define IPMRA_CREPORT_MAX (__IPMRA_CREPORT_MAX - 1)
|
||||
|
@ -1038,10 +1038,13 @@ static int ipmr_cache_report(struct mr_table *mrt,
|
||||
memcpy(msg, skb_network_header(pkt), sizeof(struct iphdr));
|
||||
msg->im_msgtype = assert;
|
||||
msg->im_mbz = 0;
|
||||
if (assert == IGMPMSG_WRVIFWHOLE)
|
||||
if (assert == IGMPMSG_WRVIFWHOLE) {
|
||||
msg->im_vif = vifi;
|
||||
else
|
||||
msg->im_vif_hi = vifi >> 8;
|
||||
} else {
|
||||
msg->im_vif = mrt->mroute_reg_vif_num;
|
||||
msg->im_vif_hi = mrt->mroute_reg_vif_num >> 8;
|
||||
}
|
||||
ip_hdr(skb)->ihl = sizeof(struct iphdr) >> 2;
|
||||
ip_hdr(skb)->tot_len = htons(ntohs(ip_hdr(pkt)->tot_len) +
|
||||
sizeof(struct iphdr));
|
||||
@ -1054,6 +1057,7 @@ static int ipmr_cache_report(struct mr_table *mrt,
|
||||
ip_hdr(skb)->protocol = 0;
|
||||
msg = (struct igmpmsg *)skb_network_header(skb);
|
||||
msg->im_vif = vifi;
|
||||
msg->im_vif_hi = vifi >> 8;
|
||||
skb_dst_set(skb, dst_clone(skb_dst(pkt)));
|
||||
/* Add our header */
|
||||
igmp = skb_put(skb, sizeof(struct igmphdr));
|
||||
@ -2396,6 +2400,7 @@ static size_t igmpmsg_netlink_msgsize(size_t payloadlen)
|
||||
+ nla_total_size(4) /* IPMRA_CREPORT_VIF_ID */
|
||||
+ nla_total_size(4) /* IPMRA_CREPORT_SRC_ADDR */
|
||||
+ nla_total_size(4) /* IPMRA_CREPORT_DST_ADDR */
|
||||
+ nla_total_size(4) /* IPMRA_CREPORT_TABLE */
|
||||
/* IPMRA_CREPORT_PKT */
|
||||
+ nla_total_size(payloadlen)
|
||||
;
|
||||
@ -2427,11 +2432,12 @@ static void igmpmsg_netlink_event(struct mr_table *mrt, struct sk_buff *pkt)
|
||||
rtgenm = nlmsg_data(nlh);
|
||||
rtgenm->rtgen_family = RTNL_FAMILY_IPMR;
|
||||
if (nla_put_u8(skb, IPMRA_CREPORT_MSGTYPE, msg->im_msgtype) ||
|
||||
nla_put_u32(skb, IPMRA_CREPORT_VIF_ID, msg->im_vif) ||
|
||||
nla_put_u32(skb, IPMRA_CREPORT_VIF_ID, msg->im_vif | (msg->im_vif_hi << 8)) ||
|
||||
nla_put_in_addr(skb, IPMRA_CREPORT_SRC_ADDR,
|
||||
msg->im_src.s_addr) ||
|
||||
nla_put_in_addr(skb, IPMRA_CREPORT_DST_ADDR,
|
||||
msg->im_dst.s_addr))
|
||||
msg->im_dst.s_addr) ||
|
||||
nla_put_u32(skb, IPMRA_CREPORT_TABLE, mrt->id))
|
||||
goto nla_put_failure;
|
||||
|
||||
nla = nla_reserve(skb, IPMRA_CREPORT_PKT, payloadlen);
|
||||
|
Loading…
Reference in New Issue
Block a user