@@ -81,6 +81,7 @@ static int ip6gre_tunnel_init(struct net_device *dev);
8181static void ip6gre_tunnel_setup (struct net_device * dev );
8282static void ip6gre_tunnel_link (struct ip6gre_net * ign , struct ip6_tnl * t );
8383static void ip6gre_tnl_link_config (struct ip6_tnl * t , int set_mtu );
84+ static void ip6erspan_tnl_link_config (struct ip6_tnl * t , int set_mtu );
8485
8586/* Tunnel hash table */
8687
@@ -698,6 +699,9 @@ static netdev_tx_t __gre6_xmit(struct sk_buff *skb,
698699 else
699700 fl6 -> daddr = tunnel -> parms .raddr ;
700701
702+ if (skb_cow_head (skb , dev -> needed_headroom ?: tunnel -> hlen ))
703+ return - ENOMEM ;
704+
701705 /* Push GRE header. */
702706 protocol = (dev -> type == ARPHRD_ETHER ) ? htons (ETH_P_TEB ) : proto ;
703707
@@ -908,7 +912,7 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb,
908912 truncate = true;
909913 }
910914
911- if (skb_cow_head (skb , dev -> needed_headroom ))
915+ if (skb_cow_head (skb , dev -> needed_headroom ?: t -> hlen ))
912916 goto tx_err ;
913917
914918 t -> parms .o_flags &= ~TUNNEL_KEY ;
@@ -1022,12 +1026,11 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb,
10221026 return NETDEV_TX_OK ;
10231027}
10241028
1025- static void ip6gre_tnl_link_config (struct ip6_tnl * t , int set_mtu )
1029+ static void ip6gre_tnl_link_config_common (struct ip6_tnl * t )
10261030{
10271031 struct net_device * dev = t -> dev ;
10281032 struct __ip6_tnl_parm * p = & t -> parms ;
10291033 struct flowi6 * fl6 = & t -> fl .u .ip6 ;
1030- int t_hlen ;
10311034
10321035 if (dev -> type != ARPHRD_ETHER ) {
10331036 memcpy (dev -> dev_addr , & p -> laddr , sizeof (struct in6_addr ));
@@ -1054,12 +1057,13 @@ static void ip6gre_tnl_link_config(struct ip6_tnl *t, int set_mtu)
10541057 dev -> flags |= IFF_POINTOPOINT ;
10551058 else
10561059 dev -> flags &= ~IFF_POINTOPOINT ;
1060+ }
10571061
1058- t -> tun_hlen = gre_calc_hlen ( t -> parms . o_flags );
1059-
1060- t -> hlen = t -> encap_hlen + t -> tun_hlen ;
1061-
1062- t_hlen = t -> hlen + sizeof ( struct ipv6hdr ) ;
1062+ static void ip6gre_tnl_link_config_route ( struct ip6_tnl * t , int set_mtu ,
1063+ int t_hlen )
1064+ {
1065+ const struct __ip6_tnl_parm * p = & t -> parms ;
1066+ struct net_device * dev = t -> dev ;
10631067
10641068 if (p -> flags & IP6_TNL_F_CAP_XMIT ) {
10651069 int strict = (ipv6_addr_type (& p -> raddr ) &
@@ -1091,8 +1095,26 @@ static void ip6gre_tnl_link_config(struct ip6_tnl *t, int set_mtu)
10911095 }
10921096}
10931097
1094- static int ip6gre_tnl_change (struct ip6_tnl * t ,
1095- const struct __ip6_tnl_parm * p , int set_mtu )
1098+ static int ip6gre_calc_hlen (struct ip6_tnl * tunnel )
1099+ {
1100+ int t_hlen ;
1101+
1102+ tunnel -> tun_hlen = gre_calc_hlen (tunnel -> parms .o_flags );
1103+ tunnel -> hlen = tunnel -> tun_hlen + tunnel -> encap_hlen ;
1104+
1105+ t_hlen = tunnel -> hlen + sizeof (struct ipv6hdr );
1106+ tunnel -> dev -> hard_header_len = LL_MAX_HEADER + t_hlen ;
1107+ return t_hlen ;
1108+ }
1109+
1110+ static void ip6gre_tnl_link_config (struct ip6_tnl * t , int set_mtu )
1111+ {
1112+ ip6gre_tnl_link_config_common (t );
1113+ ip6gre_tnl_link_config_route (t , set_mtu , ip6gre_calc_hlen (t ));
1114+ }
1115+
1116+ static void ip6gre_tnl_copy_tnl_parm (struct ip6_tnl * t ,
1117+ const struct __ip6_tnl_parm * p )
10961118{
10971119 t -> parms .laddr = p -> laddr ;
10981120 t -> parms .raddr = p -> raddr ;
@@ -1108,6 +1130,12 @@ static int ip6gre_tnl_change(struct ip6_tnl *t,
11081130 t -> parms .o_flags = p -> o_flags ;
11091131 t -> parms .fwmark = p -> fwmark ;
11101132 dst_cache_reset (& t -> dst_cache );
1133+ }
1134+
1135+ static int ip6gre_tnl_change (struct ip6_tnl * t , const struct __ip6_tnl_parm * p ,
1136+ int set_mtu )
1137+ {
1138+ ip6gre_tnl_copy_tnl_parm (t , p );
11111139 ip6gre_tnl_link_config (t , set_mtu );
11121140 return 0 ;
11131141}
@@ -1384,11 +1412,7 @@ static int ip6gre_tunnel_init_common(struct net_device *dev)
13841412 return ret ;
13851413 }
13861414
1387- tunnel -> tun_hlen = gre_calc_hlen (tunnel -> parms .o_flags );
1388- tunnel -> hlen = tunnel -> tun_hlen + tunnel -> encap_hlen ;
1389- t_hlen = tunnel -> hlen + sizeof (struct ipv6hdr );
1390-
1391- dev -> hard_header_len = LL_MAX_HEADER + t_hlen ;
1415+ t_hlen = ip6gre_calc_hlen (tunnel );
13921416 dev -> mtu = ETH_DATA_LEN - t_hlen ;
13931417 if (dev -> type == ARPHRD_ETHER )
13941418 dev -> mtu -= ETH_HLEN ;
@@ -1731,6 +1755,19 @@ static const struct net_device_ops ip6gre_tap_netdev_ops = {
17311755 .ndo_get_iflink = ip6_tnl_get_iflink ,
17321756};
17331757
1758+ static int ip6erspan_calc_hlen (struct ip6_tnl * tunnel )
1759+ {
1760+ int t_hlen ;
1761+
1762+ tunnel -> tun_hlen = 8 ;
1763+ tunnel -> hlen = tunnel -> tun_hlen + tunnel -> encap_hlen +
1764+ erspan_hdr_len (tunnel -> parms .erspan_ver );
1765+
1766+ t_hlen = tunnel -> hlen + sizeof (struct ipv6hdr );
1767+ tunnel -> dev -> hard_header_len = LL_MAX_HEADER + t_hlen ;
1768+ return t_hlen ;
1769+ }
1770+
17341771static int ip6erspan_tap_init (struct net_device * dev )
17351772{
17361773 struct ip6_tnl * tunnel ;
@@ -1754,20 +1791,15 @@ static int ip6erspan_tap_init(struct net_device *dev)
17541791 return ret ;
17551792 }
17561793
1757- tunnel -> tun_hlen = 8 ;
1758- tunnel -> hlen = tunnel -> tun_hlen + tunnel -> encap_hlen +
1759- erspan_hdr_len (tunnel -> parms .erspan_ver );
1760- t_hlen = tunnel -> hlen + sizeof (struct ipv6hdr );
1761-
1762- dev -> hard_header_len = LL_MAX_HEADER + t_hlen ;
1794+ t_hlen = ip6erspan_calc_hlen (tunnel );
17631795 dev -> mtu = ETH_DATA_LEN - t_hlen ;
17641796 if (dev -> type == ARPHRD_ETHER )
17651797 dev -> mtu -= ETH_HLEN ;
17661798 if (!(tunnel -> parms .flags & IP6_TNL_F_IGN_ENCAP_LIMIT ))
17671799 dev -> mtu -= 8 ;
17681800
17691801 dev -> priv_flags |= IFF_LIVE_ADDR_CHANGE ;
1770- ip6gre_tnl_link_config (tunnel , 1 );
1802+ ip6erspan_tnl_link_config (tunnel , 1 );
17711803
17721804 return 0 ;
17731805}
@@ -1838,9 +1870,9 @@ static bool ip6gre_netlink_encap_parms(struct nlattr *data[],
18381870 return ret ;
18391871}
18401872
1841- static int ip6gre_newlink (struct net * src_net , struct net_device * dev ,
1842- struct nlattr * tb [], struct nlattr * data [],
1843- struct netlink_ext_ack * extack )
1873+ static int ip6gre_newlink_common (struct net * src_net , struct net_device * dev ,
1874+ struct nlattr * tb [], struct nlattr * data [],
1875+ struct netlink_ext_ack * extack )
18441876{
18451877 struct ip6_tnl * nt ;
18461878 struct net * net = dev_net (dev );
@@ -1877,49 +1909,76 @@ static int ip6gre_newlink(struct net *src_net, struct net_device *dev,
18771909 if (err )
18781910 goto out ;
18791911
1880- ip6gre_tnl_link_config (nt , !tb [IFLA_MTU ]);
1881-
18821912 if (tb [IFLA_MTU ])
18831913 ip6_tnl_change_mtu (dev , nla_get_u32 (tb [IFLA_MTU ]));
18841914
18851915 dev_hold (dev );
1886- ip6gre_tunnel_link (ign , nt );
18871916
18881917out :
18891918 return err ;
18901919}
18911920
1892- static int ip6gre_changelink (struct net_device * dev , struct nlattr * tb [],
1893- struct nlattr * data [],
1894- struct netlink_ext_ack * extack )
1921+ static int ip6gre_newlink (struct net * src_net , struct net_device * dev ,
1922+ struct nlattr * tb [], struct nlattr * data [],
1923+ struct netlink_ext_ack * extack )
1924+ {
1925+ int err = ip6gre_newlink_common (src_net , dev , tb , data , extack );
1926+ struct ip6_tnl * nt = netdev_priv (dev );
1927+ struct net * net = dev_net (dev );
1928+
1929+ if (!err ) {
1930+ ip6gre_tnl_link_config (nt , !tb [IFLA_MTU ]);
1931+ ip6gre_tunnel_link (net_generic (net , ip6gre_net_id ), nt );
1932+ }
1933+ return err ;
1934+ }
1935+
1936+ static struct ip6_tnl *
1937+ ip6gre_changelink_common (struct net_device * dev , struct nlattr * tb [],
1938+ struct nlattr * data [], struct __ip6_tnl_parm * p_p ,
1939+ struct netlink_ext_ack * extack )
18951940{
18961941 struct ip6_tnl * t , * nt = netdev_priv (dev );
18971942 struct net * net = nt -> net ;
18981943 struct ip6gre_net * ign = net_generic (net , ip6gre_net_id );
1899- struct __ip6_tnl_parm p ;
19001944 struct ip_tunnel_encap ipencap ;
19011945
19021946 if (dev == ign -> fb_tunnel_dev )
1903- return - EINVAL ;
1947+ return ERR_PTR ( - EINVAL ) ;
19041948
19051949 if (ip6gre_netlink_encap_parms (data , & ipencap )) {
19061950 int err = ip6_tnl_encap_setup (nt , & ipencap );
19071951
19081952 if (err < 0 )
1909- return err ;
1953+ return ERR_PTR ( err ) ;
19101954 }
19111955
1912- ip6gre_netlink_parms (data , & p );
1956+ ip6gre_netlink_parms (data , p_p );
19131957
1914- t = ip6gre_tunnel_locate (net , & p , 0 );
1958+ t = ip6gre_tunnel_locate (net , p_p , 0 );
19151959
19161960 if (t ) {
19171961 if (t -> dev != dev )
1918- return - EEXIST ;
1962+ return ERR_PTR ( - EEXIST ) ;
19191963 } else {
19201964 t = nt ;
19211965 }
19221966
1967+ return t ;
1968+ }
1969+
1970+ static int ip6gre_changelink (struct net_device * dev , struct nlattr * tb [],
1971+ struct nlattr * data [],
1972+ struct netlink_ext_ack * extack )
1973+ {
1974+ struct ip6gre_net * ign = net_generic (dev_net (dev ), ip6gre_net_id );
1975+ struct __ip6_tnl_parm p ;
1976+ struct ip6_tnl * t ;
1977+
1978+ t = ip6gre_changelink_common (dev , tb , data , & p , extack );
1979+ if (IS_ERR (t ))
1980+ return PTR_ERR (t );
1981+
19231982 ip6gre_tunnel_unlink (ign , t );
19241983 ip6gre_tnl_change (t , & p , !tb [IFLA_MTU ]);
19251984 ip6gre_tunnel_link (ign , t );
@@ -2071,6 +2130,53 @@ static void ip6erspan_tap_setup(struct net_device *dev)
20712130 netif_keep_dst (dev );
20722131}
20732132
2133+ static int ip6erspan_newlink (struct net * src_net , struct net_device * dev ,
2134+ struct nlattr * tb [], struct nlattr * data [],
2135+ struct netlink_ext_ack * extack )
2136+ {
2137+ int err = ip6gre_newlink_common (src_net , dev , tb , data , extack );
2138+ struct ip6_tnl * nt = netdev_priv (dev );
2139+ struct net * net = dev_net (dev );
2140+
2141+ if (!err ) {
2142+ ip6erspan_tnl_link_config (nt , !tb [IFLA_MTU ]);
2143+ ip6gre_tunnel_link (net_generic (net , ip6gre_net_id ), nt );
2144+ }
2145+ return err ;
2146+ }
2147+
2148+ static void ip6erspan_tnl_link_config (struct ip6_tnl * t , int set_mtu )
2149+ {
2150+ ip6gre_tnl_link_config_common (t );
2151+ ip6gre_tnl_link_config_route (t , set_mtu , ip6erspan_calc_hlen (t ));
2152+ }
2153+
2154+ static int ip6erspan_tnl_change (struct ip6_tnl * t ,
2155+ const struct __ip6_tnl_parm * p , int set_mtu )
2156+ {
2157+ ip6gre_tnl_copy_tnl_parm (t , p );
2158+ ip6erspan_tnl_link_config (t , set_mtu );
2159+ return 0 ;
2160+ }
2161+
2162+ static int ip6erspan_changelink (struct net_device * dev , struct nlattr * tb [],
2163+ struct nlattr * data [],
2164+ struct netlink_ext_ack * extack )
2165+ {
2166+ struct ip6gre_net * ign = net_generic (dev_net (dev ), ip6gre_net_id );
2167+ struct __ip6_tnl_parm p ;
2168+ struct ip6_tnl * t ;
2169+
2170+ t = ip6gre_changelink_common (dev , tb , data , & p , extack );
2171+ if (IS_ERR (t ))
2172+ return PTR_ERR (t );
2173+
2174+ ip6gre_tunnel_unlink (ign , t );
2175+ ip6erspan_tnl_change (t , & p , !tb [IFLA_MTU ]);
2176+ ip6gre_tunnel_link (ign , t );
2177+ return 0 ;
2178+ }
2179+
20742180static struct rtnl_link_ops ip6gre_link_ops __read_mostly = {
20752181 .kind = "ip6gre" ,
20762182 .maxtype = IFLA_GRE_MAX ,
@@ -2107,8 +2213,8 @@ static struct rtnl_link_ops ip6erspan_tap_ops __read_mostly = {
21072213 .priv_size = sizeof (struct ip6_tnl ),
21082214 .setup = ip6erspan_tap_setup ,
21092215 .validate = ip6erspan_tap_validate ,
2110- .newlink = ip6gre_newlink ,
2111- .changelink = ip6gre_changelink ,
2216+ .newlink = ip6erspan_newlink ,
2217+ .changelink = ip6erspan_changelink ,
21122218 .get_size = ip6gre_get_size ,
21132219 .fill_info = ip6gre_fill_info ,
21142220 .get_link_net = ip6_tnl_get_link_net ,
0 commit comments