aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/sit.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/sit.c')
-rw-r--r--net/ipv6/sit.c123
1 files changed, 107 insertions, 16 deletions
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 6163f851dc01..6eab37cf5345 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -812,9 +812,9 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
812 const struct ipv6hdr *iph6 = ipv6_hdr(skb); 812 const struct ipv6hdr *iph6 = ipv6_hdr(skb);
813 u8 tos = tunnel->parms.iph.tos; 813 u8 tos = tunnel->parms.iph.tos;
814 __be16 df = tiph->frag_off; 814 __be16 df = tiph->frag_off;
815 struct rtable *rt; /* Route to the other host */ 815 struct rtable *rt; /* Route to the other host */
816 struct net_device *tdev; /* Device to other host */ 816 struct net_device *tdev; /* Device to other host */
817 unsigned int max_headroom; /* The extra header space needed */ 817 unsigned int max_headroom; /* The extra header space needed */
818 __be32 dst = tiph->daddr; 818 __be32 dst = tiph->daddr;
819 struct flowi4 fl4; 819 struct flowi4 fl4;
820 int mtu; 820 int mtu;
@@ -822,6 +822,8 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
822 int addr_type; 822 int addr_type;
823 u8 ttl; 823 u8 ttl;
824 int err; 824 int err;
825 u8 protocol = IPPROTO_IPV6;
826 int t_hlen = tunnel->hlen + sizeof(struct iphdr);
825 827
826 if (skb->protocol != htons(ETH_P_IPV6)) 828 if (skb->protocol != htons(ETH_P_IPV6))
827 goto tx_error; 829 goto tx_error;
@@ -911,8 +913,14 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
911 goto tx_error; 913 goto tx_error;
912 } 914 }
913 915
916 skb = iptunnel_handle_offloads(skb, false, SKB_GSO_SIT);
917 if (IS_ERR(skb)) {
918 ip_rt_put(rt);
919 goto out;
920 }
921
914 if (df) { 922 if (df) {
915 mtu = dst_mtu(&rt->dst) - sizeof(struct iphdr); 923 mtu = dst_mtu(&rt->dst) - t_hlen;
916 924
917 if (mtu < 68) { 925 if (mtu < 68) {
918 dev->stats.collisions++; 926 dev->stats.collisions++;
@@ -947,7 +955,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
947 /* 955 /*
948 * Okay, now see if we can stuff it in the buffer as-is. 956 * Okay, now see if we can stuff it in the buffer as-is.
949 */ 957 */
950 max_headroom = LL_RESERVED_SPACE(tdev)+sizeof(struct iphdr); 958 max_headroom = LL_RESERVED_SPACE(tdev) + t_hlen;
951 959
952 if (skb_headroom(skb) < max_headroom || skb_shared(skb) || 960 if (skb_headroom(skb) < max_headroom || skb_shared(skb) ||
953 (skb_cloned(skb) && !skb_clone_writable(skb, 0))) { 961 (skb_cloned(skb) && !skb_clone_writable(skb, 0))) {
@@ -969,14 +977,15 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
969 ttl = iph6->hop_limit; 977 ttl = iph6->hop_limit;
970 tos = INET_ECN_encapsulate(tos, ipv6_get_dsfield(iph6)); 978 tos = INET_ECN_encapsulate(tos, ipv6_get_dsfield(iph6));
971 979
972 skb = iptunnel_handle_offloads(skb, false, SKB_GSO_SIT); 980 if (ip_tunnel_encap(skb, tunnel, &protocol, &fl4) < 0) {
973 if (IS_ERR(skb)) {
974 ip_rt_put(rt); 981 ip_rt_put(rt);
975 goto out; 982 goto tx_error;
976 } 983 }
977 984
985 skb_set_inner_ipproto(skb, IPPROTO_IPV6);
986
978 err = iptunnel_xmit(skb->sk, rt, skb, fl4.saddr, fl4.daddr, 987 err = iptunnel_xmit(skb->sk, rt, skb, fl4.saddr, fl4.daddr,
979 IPPROTO_IPV6, tos, ttl, df, 988 protocol, tos, ttl, df,
980 !net_eq(tunnel->net, dev_net(dev))); 989 !net_eq(tunnel->net, dev_net(dev)));
981 iptunnel_xmit_stats(err, &dev->stats, dev->tstats); 990 iptunnel_xmit_stats(err, &dev->stats, dev->tstats);
982 return NETDEV_TX_OK; 991 return NETDEV_TX_OK;
@@ -999,6 +1008,8 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
999 if (IS_ERR(skb)) 1008 if (IS_ERR(skb))
1000 goto out; 1009 goto out;
1001 1010
1011 skb_set_inner_ipproto(skb, IPPROTO_IPIP);
1012
1002 ip_tunnel_xmit(skb, dev, tiph, IPPROTO_IPIP); 1013 ip_tunnel_xmit(skb, dev, tiph, IPPROTO_IPIP);
1003 return NETDEV_TX_OK; 1014 return NETDEV_TX_OK;
1004out: 1015out:
@@ -1059,8 +1070,10 @@ static void ipip6_tunnel_bind_dev(struct net_device *dev)
1059 tdev = __dev_get_by_index(tunnel->net, tunnel->parms.link); 1070 tdev = __dev_get_by_index(tunnel->net, tunnel->parms.link);
1060 1071
1061 if (tdev) { 1072 if (tdev) {
1073 int t_hlen = tunnel->hlen + sizeof(struct iphdr);
1074
1062 dev->hard_header_len = tdev->hard_header_len + sizeof(struct iphdr); 1075 dev->hard_header_len = tdev->hard_header_len + sizeof(struct iphdr);
1063 dev->mtu = tdev->mtu - sizeof(struct iphdr); 1076 dev->mtu = tdev->mtu - t_hlen;
1064 if (dev->mtu < IPV6_MIN_MTU) 1077 if (dev->mtu < IPV6_MIN_MTU)
1065 dev->mtu = IPV6_MIN_MTU; 1078 dev->mtu = IPV6_MIN_MTU;
1066 } 1079 }
@@ -1123,7 +1136,7 @@ static int ipip6_tunnel_update_6rd(struct ip_tunnel *t,
1123#endif 1136#endif
1124 1137
1125static int 1138static int
1126ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) 1139ipip6_tunnel_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1127{ 1140{
1128 int err = 0; 1141 int err = 0;
1129 struct ip_tunnel_parm p; 1142 struct ip_tunnel_parm p;
@@ -1307,7 +1320,10 @@ done:
1307 1320
1308static int ipip6_tunnel_change_mtu(struct net_device *dev, int new_mtu) 1321static int ipip6_tunnel_change_mtu(struct net_device *dev, int new_mtu)
1309{ 1322{
1310 if (new_mtu < IPV6_MIN_MTU || new_mtu > 0xFFF8 - sizeof(struct iphdr)) 1323 struct ip_tunnel *tunnel = netdev_priv(dev);
1324 int t_hlen = tunnel->hlen + sizeof(struct iphdr);
1325
1326 if (new_mtu < IPV6_MIN_MTU || new_mtu > 0xFFF8 - t_hlen)
1311 return -EINVAL; 1327 return -EINVAL;
1312 dev->mtu = new_mtu; 1328 dev->mtu = new_mtu;
1313 return 0; 1329 return 0;
@@ -1338,14 +1354,17 @@ static void ipip6_dev_free(struct net_device *dev)
1338 1354
1339static void ipip6_tunnel_setup(struct net_device *dev) 1355static void ipip6_tunnel_setup(struct net_device *dev)
1340{ 1356{
1357 struct ip_tunnel *tunnel = netdev_priv(dev);
1358 int t_hlen = tunnel->hlen + sizeof(struct iphdr);
1359
1341 dev->netdev_ops = &ipip6_netdev_ops; 1360 dev->netdev_ops = &ipip6_netdev_ops;
1342 dev->destructor = ipip6_dev_free; 1361 dev->destructor = ipip6_dev_free;
1343 1362
1344 dev->type = ARPHRD_SIT; 1363 dev->type = ARPHRD_SIT;
1345 dev->hard_header_len = LL_MAX_HEADER + sizeof(struct iphdr); 1364 dev->hard_header_len = LL_MAX_HEADER + t_hlen;
1346 dev->mtu = ETH_DATA_LEN - sizeof(struct iphdr); 1365 dev->mtu = ETH_DATA_LEN - t_hlen;
1347 dev->flags = IFF_NOARP; 1366 dev->flags = IFF_NOARP;
1348 dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; 1367 netif_keep_dst(dev);
1349 dev->iflink = 0; 1368 dev->iflink = 0;
1350 dev->addr_len = 4; 1369 dev->addr_len = 4;
1351 dev->features |= NETIF_F_LLTX; 1370 dev->features |= NETIF_F_LLTX;
@@ -1466,6 +1485,40 @@ static void ipip6_netlink_parms(struct nlattr *data[],
1466 1485
1467} 1486}
1468 1487
1488/* This function returns true when ENCAP attributes are present in the nl msg */
1489static bool ipip6_netlink_encap_parms(struct nlattr *data[],
1490 struct ip_tunnel_encap *ipencap)
1491{
1492 bool ret = false;
1493
1494 memset(ipencap, 0, sizeof(*ipencap));
1495
1496 if (!data)
1497 return ret;
1498
1499 if (data[IFLA_IPTUN_ENCAP_TYPE]) {
1500 ret = true;
1501 ipencap->type = nla_get_u16(data[IFLA_IPTUN_ENCAP_TYPE]);
1502 }
1503
1504 if (data[IFLA_IPTUN_ENCAP_FLAGS]) {
1505 ret = true;
1506 ipencap->flags = nla_get_u16(data[IFLA_IPTUN_ENCAP_FLAGS]);
1507 }
1508
1509 if (data[IFLA_IPTUN_ENCAP_SPORT]) {
1510 ret = true;
1511 ipencap->sport = nla_get_u16(data[IFLA_IPTUN_ENCAP_SPORT]);
1512 }
1513
1514 if (data[IFLA_IPTUN_ENCAP_DPORT]) {
1515 ret = true;
1516 ipencap->dport = nla_get_u16(data[IFLA_IPTUN_ENCAP_DPORT]);
1517 }
1518
1519 return ret;
1520}
1521
1469#ifdef CONFIG_IPV6_SIT_6RD 1522#ifdef CONFIG_IPV6_SIT_6RD
1470/* This function returns true when 6RD attributes are present in the nl msg */ 1523/* This function returns true when 6RD attributes are present in the nl msg */
1471static bool ipip6_netlink_6rd_parms(struct nlattr *data[], 1524static bool ipip6_netlink_6rd_parms(struct nlattr *data[],
@@ -1509,12 +1562,20 @@ static int ipip6_newlink(struct net *src_net, struct net_device *dev,
1509{ 1562{
1510 struct net *net = dev_net(dev); 1563 struct net *net = dev_net(dev);
1511 struct ip_tunnel *nt; 1564 struct ip_tunnel *nt;
1565 struct ip_tunnel_encap ipencap;
1512#ifdef CONFIG_IPV6_SIT_6RD 1566#ifdef CONFIG_IPV6_SIT_6RD
1513 struct ip_tunnel_6rd ip6rd; 1567 struct ip_tunnel_6rd ip6rd;
1514#endif 1568#endif
1515 int err; 1569 int err;
1516 1570
1517 nt = netdev_priv(dev); 1571 nt = netdev_priv(dev);
1572
1573 if (ipip6_netlink_encap_parms(data, &ipencap)) {
1574 err = ip_tunnel_encap_setup(nt, &ipencap);
1575 if (err < 0)
1576 return err;
1577 }
1578
1518 ipip6_netlink_parms(data, &nt->parms); 1579 ipip6_netlink_parms(data, &nt->parms);
1519 1580
1520 if (ipip6_tunnel_locate(net, &nt->parms, 0)) 1581 if (ipip6_tunnel_locate(net, &nt->parms, 0))
@@ -1537,15 +1598,23 @@ static int ipip6_changelink(struct net_device *dev, struct nlattr *tb[],
1537{ 1598{
1538 struct ip_tunnel *t = netdev_priv(dev); 1599 struct ip_tunnel *t = netdev_priv(dev);
1539 struct ip_tunnel_parm p; 1600 struct ip_tunnel_parm p;
1601 struct ip_tunnel_encap ipencap;
1540 struct net *net = t->net; 1602 struct net *net = t->net;
1541 struct sit_net *sitn = net_generic(net, sit_net_id); 1603 struct sit_net *sitn = net_generic(net, sit_net_id);
1542#ifdef CONFIG_IPV6_SIT_6RD 1604#ifdef CONFIG_IPV6_SIT_6RD
1543 struct ip_tunnel_6rd ip6rd; 1605 struct ip_tunnel_6rd ip6rd;
1544#endif 1606#endif
1607 int err;
1545 1608
1546 if (dev == sitn->fb_tunnel_dev) 1609 if (dev == sitn->fb_tunnel_dev)
1547 return -EINVAL; 1610 return -EINVAL;
1548 1611
1612 if (ipip6_netlink_encap_parms(data, &ipencap)) {
1613 err = ip_tunnel_encap_setup(t, &ipencap);
1614 if (err < 0)
1615 return err;
1616 }
1617
1549 ipip6_netlink_parms(data, &p); 1618 ipip6_netlink_parms(data, &p);
1550 1619
1551 if (((dev->flags & IFF_POINTOPOINT) && !p.iph.daddr) || 1620 if (((dev->flags & IFF_POINTOPOINT) && !p.iph.daddr) ||
@@ -1599,6 +1668,14 @@ static size_t ipip6_get_size(const struct net_device *dev)
1599 /* IFLA_IPTUN_6RD_RELAY_PREFIXLEN */ 1668 /* IFLA_IPTUN_6RD_RELAY_PREFIXLEN */
1600 nla_total_size(2) + 1669 nla_total_size(2) +
1601#endif 1670#endif
1671 /* IFLA_IPTUN_ENCAP_TYPE */
1672 nla_total_size(2) +
1673 /* IFLA_IPTUN_ENCAP_FLAGS */
1674 nla_total_size(2) +
1675 /* IFLA_IPTUN_ENCAP_SPORT */
1676 nla_total_size(2) +
1677 /* IFLA_IPTUN_ENCAP_DPORT */
1678 nla_total_size(2) +
1602 0; 1679 0;
1603} 1680}
1604 1681
@@ -1630,6 +1707,16 @@ static int ipip6_fill_info(struct sk_buff *skb, const struct net_device *dev)
1630 goto nla_put_failure; 1707 goto nla_put_failure;
1631#endif 1708#endif
1632 1709
1710 if (nla_put_u16(skb, IFLA_IPTUN_ENCAP_TYPE,
1711 tunnel->encap.type) ||
1712 nla_put_u16(skb, IFLA_IPTUN_ENCAP_SPORT,
1713 tunnel->encap.sport) ||
1714 nla_put_u16(skb, IFLA_IPTUN_ENCAP_DPORT,
1715 tunnel->encap.dport) ||
1716 nla_put_u16(skb, IFLA_IPTUN_ENCAP_FLAGS,
1717 tunnel->encap.dport))
1718 goto nla_put_failure;
1719
1633 return 0; 1720 return 0;
1634 1721
1635nla_put_failure: 1722nla_put_failure:
@@ -1651,6 +1738,10 @@ static const struct nla_policy ipip6_policy[IFLA_IPTUN_MAX + 1] = {
1651 [IFLA_IPTUN_6RD_PREFIXLEN] = { .type = NLA_U16 }, 1738 [IFLA_IPTUN_6RD_PREFIXLEN] = { .type = NLA_U16 },
1652 [IFLA_IPTUN_6RD_RELAY_PREFIXLEN] = { .type = NLA_U16 }, 1739 [IFLA_IPTUN_6RD_RELAY_PREFIXLEN] = { .type = NLA_U16 },
1653#endif 1740#endif
1741 [IFLA_IPTUN_ENCAP_TYPE] = { .type = NLA_U16 },
1742 [IFLA_IPTUN_ENCAP_FLAGS] = { .type = NLA_U16 },
1743 [IFLA_IPTUN_ENCAP_SPORT] = { .type = NLA_U16 },
1744 [IFLA_IPTUN_ENCAP_DPORT] = { .type = NLA_U16 },
1654}; 1745};
1655 1746
1656static void ipip6_dellink(struct net_device *dev, struct list_head *head) 1747static void ipip6_dellink(struct net_device *dev, struct list_head *head)