diff options
Diffstat (limited to 'net/ipv6/mcast.c')
-rw-r--r-- | net/ipv6/mcast.c | 46 |
1 files changed, 24 insertions, 22 deletions
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index a8d6625ec782..6c2758951d60 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c | |||
@@ -988,7 +988,7 @@ int ipv6_is_mld(struct sk_buff *skb, int nexthdr) | |||
988 | if (!pskb_may_pull(skb, sizeof(struct icmp6hdr))) | 988 | if (!pskb_may_pull(skb, sizeof(struct icmp6hdr))) |
989 | return 0; | 989 | return 0; |
990 | 990 | ||
991 | pic = (struct icmp6hdr *)skb->h.raw; | 991 | pic = icmp6_hdr(skb); |
992 | 992 | ||
993 | switch (pic->icmp6_type) { | 993 | switch (pic->icmp6_type) { |
994 | case ICMPV6_MGM_QUERY: | 994 | case ICMPV6_MGM_QUERY: |
@@ -1167,11 +1167,11 @@ int igmp6_event_query(struct sk_buff *skb) | |||
1167 | return -EINVAL; | 1167 | return -EINVAL; |
1168 | 1168 | ||
1169 | /* compute payload length excluding extension headers */ | 1169 | /* compute payload length excluding extension headers */ |
1170 | len = ntohs(skb->nh.ipv6h->payload_len) + sizeof(struct ipv6hdr); | 1170 | len = ntohs(ipv6_hdr(skb)->payload_len) + sizeof(struct ipv6hdr); |
1171 | len -= (char *)skb->h.raw - (char *)skb->nh.ipv6h; | 1171 | len -= skb_network_header_len(skb); |
1172 | 1172 | ||
1173 | /* Drop queries with not link local source */ | 1173 | /* Drop queries with not link local source */ |
1174 | if (!(ipv6_addr_type(&skb->nh.ipv6h->saddr)&IPV6_ADDR_LINKLOCAL)) | 1174 | if (!(ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL)) |
1175 | return -EINVAL; | 1175 | return -EINVAL; |
1176 | 1176 | ||
1177 | idev = in6_dev_get(skb->dev); | 1177 | idev = in6_dev_get(skb->dev); |
@@ -1179,7 +1179,7 @@ int igmp6_event_query(struct sk_buff *skb) | |||
1179 | if (idev == NULL) | 1179 | if (idev == NULL) |
1180 | return 0; | 1180 | return 0; |
1181 | 1181 | ||
1182 | hdr = (struct icmp6hdr *) skb->h.raw; | 1182 | hdr = icmp6_hdr(skb); |
1183 | group = (struct in6_addr *) (hdr + 1); | 1183 | group = (struct in6_addr *) (hdr + 1); |
1184 | group_type = ipv6_addr_type(group); | 1184 | group_type = ipv6_addr_type(group); |
1185 | 1185 | ||
@@ -1212,7 +1212,7 @@ int igmp6_event_query(struct sk_buff *skb) | |||
1212 | in6_dev_put(idev); | 1212 | in6_dev_put(idev); |
1213 | return -EINVAL; | 1213 | return -EINVAL; |
1214 | } | 1214 | } |
1215 | mlh2 = (struct mld2_query *) skb->h.raw; | 1215 | mlh2 = (struct mld2_query *)skb_transport_header(skb); |
1216 | max_delay = (MLDV2_MRC(ntohs(mlh2->mrc))*HZ)/1000; | 1216 | max_delay = (MLDV2_MRC(ntohs(mlh2->mrc))*HZ)/1000; |
1217 | if (!max_delay) | 1217 | if (!max_delay) |
1218 | max_delay = 1; | 1218 | max_delay = 1; |
@@ -1235,7 +1235,7 @@ int igmp6_event_query(struct sk_buff *skb) | |||
1235 | in6_dev_put(idev); | 1235 | in6_dev_put(idev); |
1236 | return -EINVAL; | 1236 | return -EINVAL; |
1237 | } | 1237 | } |
1238 | mlh2 = (struct mld2_query *) skb->h.raw; | 1238 | mlh2 = (struct mld2_query *)skb_transport_header(skb); |
1239 | mark = 1; | 1239 | mark = 1; |
1240 | } | 1240 | } |
1241 | } else { | 1241 | } else { |
@@ -1300,10 +1300,10 @@ int igmp6_event_report(struct sk_buff *skb) | |||
1300 | if (!pskb_may_pull(skb, sizeof(struct in6_addr))) | 1300 | if (!pskb_may_pull(skb, sizeof(struct in6_addr))) |
1301 | return -EINVAL; | 1301 | return -EINVAL; |
1302 | 1302 | ||
1303 | hdr = (struct icmp6hdr*) skb->h.raw; | 1303 | hdr = icmp6_hdr(skb); |
1304 | 1304 | ||
1305 | /* Drop reports with not link local source */ | 1305 | /* Drop reports with not link local source */ |
1306 | addr_type = ipv6_addr_type(&skb->nh.ipv6h->saddr); | 1306 | addr_type = ipv6_addr_type(&ipv6_hdr(skb)->saddr); |
1307 | if (addr_type != IPV6_ADDR_ANY && | 1307 | if (addr_type != IPV6_ADDR_ANY && |
1308 | !(addr_type&IPV6_ADDR_LINKLOCAL)) | 1308 | !(addr_type&IPV6_ADDR_LINKLOCAL)) |
1309 | return -EINVAL; | 1309 | return -EINVAL; |
@@ -1411,7 +1411,7 @@ static struct sk_buff *mld_newpack(struct net_device *dev, int size) | |||
1411 | 1411 | ||
1412 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); | 1412 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); |
1413 | 1413 | ||
1414 | if (ipv6_get_lladdr(dev, &addr_buf)) { | 1414 | if (ipv6_get_lladdr(dev, &addr_buf, IFA_F_TENTATIVE)) { |
1415 | /* <draft-ietf-magma-mld-source-05.txt>: | 1415 | /* <draft-ietf-magma-mld-source-05.txt>: |
1416 | * use unspecified address as the source address | 1416 | * use unspecified address as the source address |
1417 | * when a valid link-local address is not available. | 1417 | * when a valid link-local address is not available. |
@@ -1423,8 +1423,9 @@ static struct sk_buff *mld_newpack(struct net_device *dev, int size) | |||
1423 | 1423 | ||
1424 | memcpy(skb_put(skb, sizeof(ra)), ra, sizeof(ra)); | 1424 | memcpy(skb_put(skb, sizeof(ra)), ra, sizeof(ra)); |
1425 | 1425 | ||
1426 | pmr =(struct mld2_report *)skb_put(skb, sizeof(*pmr)); | 1426 | skb_set_transport_header(skb, skb_tail_pointer(skb) - skb->data); |
1427 | skb->h.raw = (unsigned char *)pmr; | 1427 | skb_put(skb, sizeof(*pmr)); |
1428 | pmr = (struct mld2_report *)skb_transport_header(skb); | ||
1428 | pmr->type = ICMPV6_MLD2_REPORT; | 1429 | pmr->type = ICMPV6_MLD2_REPORT; |
1429 | pmr->resv1 = 0; | 1430 | pmr->resv1 = 0; |
1430 | pmr->csum = 0; | 1431 | pmr->csum = 0; |
@@ -1441,7 +1442,7 @@ static inline int mld_dev_queue_xmit2(struct sk_buff *skb) | |||
1441 | unsigned char ha[MAX_ADDR_LEN]; | 1442 | unsigned char ha[MAX_ADDR_LEN]; |
1442 | int err; | 1443 | int err; |
1443 | 1444 | ||
1444 | ndisc_mc_map(&skb->nh.ipv6h->daddr, ha, dev, 1); | 1445 | ndisc_mc_map(&ipv6_hdr(skb)->daddr, ha, dev, 1); |
1445 | err = dev->hard_header(skb, dev, ETH_P_IPV6, ha, NULL, skb->len); | 1446 | err = dev->hard_header(skb, dev, ETH_P_IPV6, ha, NULL, skb->len); |
1446 | if (err < 0) { | 1447 | if (err < 0) { |
1447 | kfree_skb(skb); | 1448 | kfree_skb(skb); |
@@ -1459,20 +1460,21 @@ static inline int mld_dev_queue_xmit(struct sk_buff *skb) | |||
1459 | 1460 | ||
1460 | static void mld_sendpack(struct sk_buff *skb) | 1461 | static void mld_sendpack(struct sk_buff *skb) |
1461 | { | 1462 | { |
1462 | struct ipv6hdr *pip6 = skb->nh.ipv6h; | 1463 | struct ipv6hdr *pip6 = ipv6_hdr(skb); |
1463 | struct mld2_report *pmr = (struct mld2_report *)skb->h.raw; | 1464 | struct mld2_report *pmr = |
1465 | (struct mld2_report *)skb_transport_header(skb); | ||
1464 | int payload_len, mldlen; | 1466 | int payload_len, mldlen; |
1465 | struct inet6_dev *idev = in6_dev_get(skb->dev); | 1467 | struct inet6_dev *idev = in6_dev_get(skb->dev); |
1466 | int err; | 1468 | int err; |
1467 | 1469 | ||
1468 | IP6_INC_STATS(idev, IPSTATS_MIB_OUTREQUESTS); | 1470 | IP6_INC_STATS(idev, IPSTATS_MIB_OUTREQUESTS); |
1469 | payload_len = skb->tail - (unsigned char *)skb->nh.ipv6h - | 1471 | payload_len = (skb->tail - skb->network_header) - sizeof(*pip6); |
1470 | sizeof(struct ipv6hdr); | 1472 | mldlen = skb->tail - skb->transport_header; |
1471 | mldlen = skb->tail - skb->h.raw; | ||
1472 | pip6->payload_len = htons(payload_len); | 1473 | pip6->payload_len = htons(payload_len); |
1473 | 1474 | ||
1474 | pmr->csum = csum_ipv6_magic(&pip6->saddr, &pip6->daddr, mldlen, | 1475 | pmr->csum = csum_ipv6_magic(&pip6->saddr, &pip6->daddr, mldlen, |
1475 | IPPROTO_ICMPV6, csum_partial(skb->h.raw, mldlen, 0)); | 1476 | IPPROTO_ICMPV6, csum_partial(skb_transport_header(skb), |
1477 | mldlen, 0)); | ||
1476 | err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev, | 1478 | err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev, |
1477 | mld_dev_queue_xmit); | 1479 | mld_dev_queue_xmit); |
1478 | if (!err) { | 1480 | if (!err) { |
@@ -1506,7 +1508,7 @@ static struct sk_buff *add_grhead(struct sk_buff *skb, struct ifmcaddr6 *pmc, | |||
1506 | pgr->grec_auxwords = 0; | 1508 | pgr->grec_auxwords = 0; |
1507 | pgr->grec_nsrcs = 0; | 1509 | pgr->grec_nsrcs = 0; |
1508 | pgr->grec_mca = pmc->mca_addr; /* structure copy */ | 1510 | pgr->grec_mca = pmc->mca_addr; /* structure copy */ |
1509 | pmr = (struct mld2_report *)skb->h.raw; | 1511 | pmr = (struct mld2_report *)skb_transport_header(skb); |
1510 | pmr->ngrec = htons(ntohs(pmr->ngrec)+1); | 1512 | pmr->ngrec = htons(ntohs(pmr->ngrec)+1); |
1511 | *ppgr = pgr; | 1513 | *ppgr = pgr; |
1512 | return skb; | 1514 | return skb; |
@@ -1539,7 +1541,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc, | |||
1539 | if (!*psf_list) | 1541 | if (!*psf_list) |
1540 | goto empty_source; | 1542 | goto empty_source; |
1541 | 1543 | ||
1542 | pmr = skb ? (struct mld2_report *)skb->h.raw : NULL; | 1544 | pmr = skb ? (struct mld2_report *)skb_transport_header(skb) : NULL; |
1543 | 1545 | ||
1544 | /* EX and TO_EX get a fresh packet, if needed */ | 1546 | /* EX and TO_EX get a fresh packet, if needed */ |
1545 | if (truncate) { | 1547 | if (truncate) { |
@@ -1791,7 +1793,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) | |||
1791 | 1793 | ||
1792 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); | 1794 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); |
1793 | 1795 | ||
1794 | if (ipv6_get_lladdr(dev, &addr_buf)) { | 1796 | if (ipv6_get_lladdr(dev, &addr_buf, IFA_F_TENTATIVE)) { |
1795 | /* <draft-ietf-magma-mld-source-05.txt>: | 1797 | /* <draft-ietf-magma-mld-source-05.txt>: |
1796 | * use unspecified address as the source address | 1798 | * use unspecified address as the source address |
1797 | * when a valid link-local address is not available. | 1799 | * when a valid link-local address is not available. |