aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/ip6_gre.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/ip6_gre.c')
-rw-r--r--net/ipv6/ip6_gre.c92
1 files changed, 54 insertions, 38 deletions
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index 09d0826742f8..26f25b6e2833 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -534,13 +534,9 @@ static int ip6erspan_rcv(struct sk_buff *skb, int gre_hdr_len,
534 struct ip6_tnl *tunnel; 534 struct ip6_tnl *tunnel;
535 u8 ver; 535 u8 ver;
536 536
537 if (unlikely(!pskb_may_pull(skb, sizeof(*ershdr))))
538 return PACKET_REJECT;
539
540 ipv6h = ipv6_hdr(skb); 537 ipv6h = ipv6_hdr(skb);
541 ershdr = (struct erspan_base_hdr *)skb->data; 538 ershdr = (struct erspan_base_hdr *)skb->data;
542 ver = ershdr->ver; 539 ver = ershdr->ver;
543 tpi->key = cpu_to_be32(get_session_id(ershdr));
544 540
545 tunnel = ip6gre_tunnel_lookup(skb->dev, 541 tunnel = ip6gre_tunnel_lookup(skb->dev,
546 &ipv6h->saddr, &ipv6h->daddr, tpi->key, 542 &ipv6h->saddr, &ipv6h->daddr, tpi->key,
@@ -922,6 +918,7 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb,
922 __u8 dsfield = false; 918 __u8 dsfield = false;
923 struct flowi6 fl6; 919 struct flowi6 fl6;
924 int err = -EINVAL; 920 int err = -EINVAL;
921 __be16 proto;
925 __u32 mtu; 922 __u32 mtu;
926 int nhoff; 923 int nhoff;
927 int thoff; 924 int thoff;
@@ -1035,8 +1032,9 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb,
1035 } 1032 }
1036 1033
1037 /* Push GRE header. */ 1034 /* Push GRE header. */
1038 gre_build_header(skb, 8, TUNNEL_SEQ, 1035 proto = (t->parms.erspan_ver == 1) ? htons(ETH_P_ERSPAN)
1039 htons(ETH_P_ERSPAN), 0, htonl(t->o_seqno++)); 1036 : htons(ETH_P_ERSPAN2);
1037 gre_build_header(skb, 8, TUNNEL_SEQ, proto, 0, htonl(t->o_seqno++));
1040 1038
1041 /* TooBig packet may have updated dst->dev's mtu */ 1039 /* TooBig packet may have updated dst->dev's mtu */
1042 if (!t->parms.collect_md && dst && dst_mtu(dst) > dst->dev->mtu) 1040 if (!t->parms.collect_md && dst && dst_mtu(dst) > dst->dev->mtu)
@@ -1169,6 +1167,10 @@ static void ip6gre_tnl_copy_tnl_parm(struct ip6_tnl *t,
1169 t->parms.i_flags = p->i_flags; 1167 t->parms.i_flags = p->i_flags;
1170 t->parms.o_flags = p->o_flags; 1168 t->parms.o_flags = p->o_flags;
1171 t->parms.fwmark = p->fwmark; 1169 t->parms.fwmark = p->fwmark;
1170 t->parms.erspan_ver = p->erspan_ver;
1171 t->parms.index = p->index;
1172 t->parms.dir = p->dir;
1173 t->parms.hwid = p->hwid;
1172 dst_cache_reset(&t->dst_cache); 1174 dst_cache_reset(&t->dst_cache);
1173} 1175}
1174 1176
@@ -1717,6 +1719,27 @@ static int ip6erspan_tap_validate(struct nlattr *tb[], struct nlattr *data[],
1717 return 0; 1719 return 0;
1718} 1720}
1719 1721
1722static void ip6erspan_set_version(struct nlattr *data[],
1723 struct __ip6_tnl_parm *parms)
1724{
1725 if (!data)
1726 return;
1727
1728 parms->erspan_ver = 1;
1729 if (data[IFLA_GRE_ERSPAN_VER])
1730 parms->erspan_ver = nla_get_u8(data[IFLA_GRE_ERSPAN_VER]);
1731
1732 if (parms->erspan_ver == 1) {
1733 if (data[IFLA_GRE_ERSPAN_INDEX])
1734 parms->index = nla_get_u32(data[IFLA_GRE_ERSPAN_INDEX]);
1735 } else if (parms->erspan_ver == 2) {
1736 if (data[IFLA_GRE_ERSPAN_DIR])
1737 parms->dir = nla_get_u8(data[IFLA_GRE_ERSPAN_DIR]);
1738 if (data[IFLA_GRE_ERSPAN_HWID])
1739 parms->hwid = nla_get_u16(data[IFLA_GRE_ERSPAN_HWID]);
1740 }
1741}
1742
1720static void ip6gre_netlink_parms(struct nlattr *data[], 1743static void ip6gre_netlink_parms(struct nlattr *data[],
1721 struct __ip6_tnl_parm *parms) 1744 struct __ip6_tnl_parm *parms)
1722{ 1745{
@@ -1765,20 +1788,6 @@ static void ip6gre_netlink_parms(struct nlattr *data[],
1765 1788
1766 if (data[IFLA_GRE_COLLECT_METADATA]) 1789 if (data[IFLA_GRE_COLLECT_METADATA])
1767 parms->collect_md = true; 1790 parms->collect_md = true;
1768
1769 parms->erspan_ver = 1;
1770 if (data[IFLA_GRE_ERSPAN_VER])
1771 parms->erspan_ver = nla_get_u8(data[IFLA_GRE_ERSPAN_VER]);
1772
1773 if (parms->erspan_ver == 1) {
1774 if (data[IFLA_GRE_ERSPAN_INDEX])
1775 parms->index = nla_get_u32(data[IFLA_GRE_ERSPAN_INDEX]);
1776 } else if (parms->erspan_ver == 2) {
1777 if (data[IFLA_GRE_ERSPAN_DIR])
1778 parms->dir = nla_get_u8(data[IFLA_GRE_ERSPAN_DIR]);
1779 if (data[IFLA_GRE_ERSPAN_HWID])
1780 parms->hwid = nla_get_u16(data[IFLA_GRE_ERSPAN_HWID]);
1781 }
1782} 1791}
1783 1792
1784static int ip6gre_tap_init(struct net_device *dev) 1793static int ip6gre_tap_init(struct net_device *dev)
@@ -2025,9 +2034,9 @@ static int ip6gre_changelink(struct net_device *dev, struct nlattr *tb[],
2025 struct nlattr *data[], 2034 struct nlattr *data[],
2026 struct netlink_ext_ack *extack) 2035 struct netlink_ext_ack *extack)
2027{ 2036{
2028 struct ip6gre_net *ign = net_generic(dev_net(dev), ip6gre_net_id); 2037 struct ip6_tnl *t = netdev_priv(dev);
2038 struct ip6gre_net *ign = net_generic(t->net, ip6gre_net_id);
2029 struct __ip6_tnl_parm p; 2039 struct __ip6_tnl_parm p;
2030 struct ip6_tnl *t;
2031 2040
2032 t = ip6gre_changelink_common(dev, tb, data, &p, extack); 2041 t = ip6gre_changelink_common(dev, tb, data, &p, extack);
2033 if (IS_ERR(t)) 2042 if (IS_ERR(t))
@@ -2096,12 +2105,31 @@ static int ip6gre_fill_info(struct sk_buff *skb, const struct net_device *dev)
2096{ 2105{
2097 struct ip6_tnl *t = netdev_priv(dev); 2106 struct ip6_tnl *t = netdev_priv(dev);
2098 struct __ip6_tnl_parm *p = &t->parms; 2107 struct __ip6_tnl_parm *p = &t->parms;
2108 __be16 o_flags = p->o_flags;
2109
2110 if (p->erspan_ver == 1 || p->erspan_ver == 2) {
2111 if (!p->collect_md)
2112 o_flags |= TUNNEL_KEY;
2113
2114 if (nla_put_u8(skb, IFLA_GRE_ERSPAN_VER, p->erspan_ver))
2115 goto nla_put_failure;
2116
2117 if (p->erspan_ver == 1) {
2118 if (nla_put_u32(skb, IFLA_GRE_ERSPAN_INDEX, p->index))
2119 goto nla_put_failure;
2120 } else {
2121 if (nla_put_u8(skb, IFLA_GRE_ERSPAN_DIR, p->dir))
2122 goto nla_put_failure;
2123 if (nla_put_u16(skb, IFLA_GRE_ERSPAN_HWID, p->hwid))
2124 goto nla_put_failure;
2125 }
2126 }
2099 2127
2100 if (nla_put_u32(skb, IFLA_GRE_LINK, p->link) || 2128 if (nla_put_u32(skb, IFLA_GRE_LINK, p->link) ||
2101 nla_put_be16(skb, IFLA_GRE_IFLAGS, 2129 nla_put_be16(skb, IFLA_GRE_IFLAGS,
2102 gre_tnl_flags_to_gre_flags(p->i_flags)) || 2130 gre_tnl_flags_to_gre_flags(p->i_flags)) ||
2103 nla_put_be16(skb, IFLA_GRE_OFLAGS, 2131 nla_put_be16(skb, IFLA_GRE_OFLAGS,
2104 gre_tnl_flags_to_gre_flags(p->o_flags)) || 2132 gre_tnl_flags_to_gre_flags(o_flags)) ||
2105 nla_put_be32(skb, IFLA_GRE_IKEY, p->i_key) || 2133 nla_put_be32(skb, IFLA_GRE_IKEY, p->i_key) ||
2106 nla_put_be32(skb, IFLA_GRE_OKEY, p->o_key) || 2134 nla_put_be32(skb, IFLA_GRE_OKEY, p->o_key) ||
2107 nla_put_in6_addr(skb, IFLA_GRE_LOCAL, &p->laddr) || 2135 nla_put_in6_addr(skb, IFLA_GRE_LOCAL, &p->laddr) ||
@@ -2110,8 +2138,7 @@ static int ip6gre_fill_info(struct sk_buff *skb, const struct net_device *dev)
2110 nla_put_u8(skb, IFLA_GRE_ENCAP_LIMIT, p->encap_limit) || 2138 nla_put_u8(skb, IFLA_GRE_ENCAP_LIMIT, p->encap_limit) ||
2111 nla_put_be32(skb, IFLA_GRE_FLOWINFO, p->flowinfo) || 2139 nla_put_be32(skb, IFLA_GRE_FLOWINFO, p->flowinfo) ||
2112 nla_put_u32(skb, IFLA_GRE_FLAGS, p->flags) || 2140 nla_put_u32(skb, IFLA_GRE_FLAGS, p->flags) ||
2113 nla_put_u32(skb, IFLA_GRE_FWMARK, p->fwmark) || 2141 nla_put_u32(skb, IFLA_GRE_FWMARK, p->fwmark))
2114 nla_put_u32(skb, IFLA_GRE_ERSPAN_INDEX, p->index))
2115 goto nla_put_failure; 2142 goto nla_put_failure;
2116 2143
2117 if (nla_put_u16(skb, IFLA_GRE_ENCAP_TYPE, 2144 if (nla_put_u16(skb, IFLA_GRE_ENCAP_TYPE,
@@ -2129,19 +2156,6 @@ static int ip6gre_fill_info(struct sk_buff *skb, const struct net_device *dev)
2129 goto nla_put_failure; 2156 goto nla_put_failure;
2130 } 2157 }
2131 2158
2132 if (nla_put_u8(skb, IFLA_GRE_ERSPAN_VER, p->erspan_ver))
2133 goto nla_put_failure;
2134
2135 if (p->erspan_ver == 1) {
2136 if (nla_put_u32(skb, IFLA_GRE_ERSPAN_INDEX, p->index))
2137 goto nla_put_failure;
2138 } else if (p->erspan_ver == 2) {
2139 if (nla_put_u8(skb, IFLA_GRE_ERSPAN_DIR, p->dir))
2140 goto nla_put_failure;
2141 if (nla_put_u16(skb, IFLA_GRE_ERSPAN_HWID, p->hwid))
2142 goto nla_put_failure;
2143 }
2144
2145 return 0; 2159 return 0;
2146 2160
2147nla_put_failure: 2161nla_put_failure:
@@ -2196,6 +2210,7 @@ static int ip6erspan_newlink(struct net *src_net, struct net_device *dev,
2196 int err; 2210 int err;
2197 2211
2198 ip6gre_netlink_parms(data, &nt->parms); 2212 ip6gre_netlink_parms(data, &nt->parms);
2213 ip6erspan_set_version(data, &nt->parms);
2199 ign = net_generic(net, ip6gre_net_id); 2214 ign = net_generic(net, ip6gre_net_id);
2200 2215
2201 if (nt->parms.collect_md) { 2216 if (nt->parms.collect_md) {
@@ -2241,6 +2256,7 @@ static int ip6erspan_changelink(struct net_device *dev, struct nlattr *tb[],
2241 if (IS_ERR(t)) 2256 if (IS_ERR(t))
2242 return PTR_ERR(t); 2257 return PTR_ERR(t);
2243 2258
2259 ip6erspan_set_version(data, &p);
2244 ip6gre_tunnel_unlink_md(ign, t); 2260 ip6gre_tunnel_unlink_md(ign, t);
2245 ip6gre_tunnel_unlink(ign, t); 2261 ip6gre_tunnel_unlink(ign, t);
2246 ip6erspan_tnl_change(t, &p, !tb[IFLA_MTU]); 2262 ip6erspan_tnl_change(t, &p, !tb[IFLA_MTU]);