aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/mcast.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/mcast.c')
-rw-r--r--net/ipv6/mcast.c46
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
1460static void mld_sendpack(struct sk_buff *skb) 1461static 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.