@@ -268,9 +268,10 @@ static bool gtp_check_ms_ipv6(struct sk_buff *skb, struct pdp_ctx *pctx,
268
268
* existing mobile subscriber.
269
269
*/
270
270
static bool gtp_check_ms (struct sk_buff * skb , struct pdp_ctx * pctx ,
271
- unsigned int hdrlen , unsigned int role )
271
+ unsigned int hdrlen , unsigned int role ,
272
+ __u16 inner_proto )
272
273
{
273
- switch (ntohs ( skb -> protocol ) ) {
274
+ switch (inner_proto ) {
274
275
case ETH_P_IP :
275
276
return gtp_check_ms_ipv4 (skb , pctx , hdrlen , role );
276
277
case ETH_P_IPV6 :
@@ -279,16 +280,47 @@ static bool gtp_check_ms(struct sk_buff *skb, struct pdp_ctx *pctx,
279
280
return false;
280
281
}
281
282
283
+ static int gtp_inner_proto (struct sk_buff * skb , unsigned int hdrlen ,
284
+ __u16 * inner_proto )
285
+ {
286
+ __u8 * ip_version , _ip_version ;
287
+
288
+ ip_version = skb_header_pointer (skb , hdrlen , sizeof (* ip_version ),
289
+ & _ip_version );
290
+ if (!ip_version )
291
+ return -1 ;
292
+
293
+ switch (* ip_version & 0xf0 ) {
294
+ case 0x40 :
295
+ * inner_proto = ETH_P_IP ;
296
+ break ;
297
+ case 0x60 :
298
+ * inner_proto = ETH_P_IPV6 ;
299
+ break ;
300
+ default :
301
+ return -1 ;
302
+ }
303
+
304
+ return 0 ;
305
+ }
306
+
282
307
static int gtp_rx (struct pdp_ctx * pctx , struct sk_buff * skb ,
283
- unsigned int hdrlen , unsigned int role )
308
+ unsigned int hdrlen , unsigned int role )
284
309
{
285
- if (!gtp_check_ms (skb , pctx , hdrlen , role )) {
310
+ __u16 inner_proto ;
311
+
312
+ if (gtp_inner_proto (skb , hdrlen , & inner_proto ) < 0 ) {
313
+ netdev_dbg (pctx -> dev , "GTP packet does not encapsulate an IP packet\n" );
314
+ return -1 ;
315
+ }
316
+
317
+ if (!gtp_check_ms (skb , pctx , hdrlen , role , inner_proto )) {
286
318
netdev_dbg (pctx -> dev , "No PDP ctx for this MS\n" );
287
319
return 1 ;
288
320
}
289
321
290
322
/* Get rid of the GTP + UDP headers. */
291
- if (iptunnel_pull_header (skb , hdrlen , skb -> protocol ,
323
+ if (iptunnel_pull_header (skb , hdrlen , htons ( inner_proto ) ,
292
324
!net_eq (sock_net (pctx -> sk ), dev_net (pctx -> dev )))) {
293
325
pctx -> dev -> stats .rx_length_errors ++ ;
294
326
goto err ;
@@ -1108,6 +1140,7 @@ static int gtp_build_skb_ip4(struct sk_buff *skb, struct net_device *dev,
1108
1140
struct gtp_pktinfo * pktinfo )
1109
1141
{
1110
1142
struct gtp_dev * gtp = netdev_priv (dev );
1143
+ struct net * net = gtp -> net ;
1111
1144
struct pdp_ctx * pctx ;
1112
1145
struct iphdr * iph ;
1113
1146
int ret ;
@@ -1128,8 +1161,21 @@ static int gtp_build_skb_ip4(struct sk_buff *skb, struct net_device *dev,
1128
1161
}
1129
1162
netdev_dbg (dev , "found PDP context %p\n" , pctx );
1130
1163
1131
- ret = gtp_build_skb_outer_ip4 (skb , dev , pktinfo , pctx ,
1132
- iph -> tos , iph -> frag_off );
1164
+ switch (pctx -> sk -> sk_family ) {
1165
+ case AF_INET :
1166
+ ret = gtp_build_skb_outer_ip4 (skb , dev , pktinfo , pctx ,
1167
+ iph -> tos , iph -> frag_off );
1168
+ break ;
1169
+ case AF_INET6 :
1170
+ ret = gtp_build_skb_outer_ip6 (net , skb , dev , pktinfo , pctx ,
1171
+ iph -> tos );
1172
+ break ;
1173
+ default :
1174
+ ret = -1 ;
1175
+ WARN_ON_ONCE (1 );
1176
+ break ;
1177
+ }
1178
+
1133
1179
if (ret < 0 )
1134
1180
return ret ;
1135
1181
@@ -1167,7 +1213,19 @@ static int gtp_build_skb_ip6(struct sk_buff *skb, struct net_device *dev,
1167
1213
1168
1214
tos = ipv6_get_dsfield (ip6h );
1169
1215
1170
- ret = gtp_build_skb_outer_ip6 (net , skb , dev , pktinfo , pctx , tos );
1216
+ switch (pctx -> sk -> sk_family ) {
1217
+ case AF_INET :
1218
+ ret = gtp_build_skb_outer_ip4 (skb , dev , pktinfo , pctx , tos , 0 );
1219
+ break ;
1220
+ case AF_INET6 :
1221
+ ret = gtp_build_skb_outer_ip6 (net , skb , dev , pktinfo , pctx , tos );
1222
+ break ;
1223
+ default :
1224
+ ret = -1 ;
1225
+ WARN_ON_ONCE (1 );
1226
+ break ;
1227
+ }
1228
+
1171
1229
if (ret < 0 )
1172
1230
return ret ;
1173
1231
@@ -1207,8 +1265,8 @@ static netdev_tx_t gtp_dev_xmit(struct sk_buff *skb, struct net_device *dev)
1207
1265
if (err < 0 )
1208
1266
goto tx_err ;
1209
1267
1210
- switch (proto ) {
1211
- case ETH_P_IP :
1268
+ switch (pktinfo . pctx -> sk -> sk_family ) {
1269
+ case AF_INET :
1212
1270
udp_tunnel_xmit_skb (pktinfo .rt , pktinfo .sk , skb ,
1213
1271
pktinfo .fl4 .saddr , pktinfo .fl4 .daddr ,
1214
1272
pktinfo .tos ,
@@ -1219,7 +1277,7 @@ static netdev_tx_t gtp_dev_xmit(struct sk_buff *skb, struct net_device *dev)
1219
1277
dev_net (dev )),
1220
1278
false);
1221
1279
break ;
1222
- case ETH_P_IPV6 :
1280
+ case AF_INET6 :
1223
1281
#if IS_ENABLED (CONFIG_IPV6 )
1224
1282
udp_tunnel6_xmit_skb (& pktinfo .rt6 -> dst , pktinfo .sk , skb , dev ,
1225
1283
& pktinfo .fl6 .saddr , & pktinfo .fl6 .daddr ,
@@ -1695,18 +1753,27 @@ static void gtp_pdp_fill(struct pdp_ctx *pctx, struct genl_info *info)
1695
1753
}
1696
1754
}
1697
1755
1756
+ static void ip_pdp_peer_fill (struct pdp_ctx * pctx , struct genl_info * info )
1757
+ {
1758
+ if (info -> attrs [GTPA_PEER_ADDRESS ]) {
1759
+ pctx -> peer .addr .s_addr =
1760
+ nla_get_be32 (info -> attrs [GTPA_PEER_ADDRESS ]);
1761
+ } else if (info -> attrs [GTPA_PEER_ADDR6 ]) {
1762
+ pctx -> peer .addr6 = nla_get_in6_addr (info -> attrs [GTPA_PEER_ADDR6 ]);
1763
+ }
1764
+ }
1765
+
1698
1766
static void ipv4_pdp_fill (struct pdp_ctx * pctx , struct genl_info * info )
1699
1767
{
1700
- pctx -> peer .addr .s_addr =
1701
- nla_get_be32 (info -> attrs [GTPA_PEER_ADDRESS ]);
1768
+ ip_pdp_peer_fill (pctx , info );
1702
1769
pctx -> ms .addr .s_addr =
1703
1770
nla_get_be32 (info -> attrs [GTPA_MS_ADDRESS ]);
1704
1771
gtp_pdp_fill (pctx , info );
1705
1772
}
1706
1773
1707
1774
static bool ipv6_pdp_fill (struct pdp_ctx * pctx , struct genl_info * info )
1708
1775
{
1709
- pctx -> peer . addr6 = nla_get_in6_addr ( info -> attrs [ GTPA_PEER_ADDR6 ] );
1776
+ ip_pdp_peer_fill ( pctx , info );
1710
1777
pctx -> ms .addr6 = nla_get_in6_addr (info -> attrs [GTPA_MS_ADDR6 ]);
1711
1778
if (pctx -> ms .addr6 .s6_addr32 [2 ] ||
1712
1779
pctx -> ms .addr6 .s6_addr32 [3 ])
@@ -1740,6 +1807,9 @@ static struct pdp_ctx *gtp_pdp_add(struct gtp_dev *gtp, struct sock *sk,
1740
1807
if (family == AF_INET6 )
1741
1808
return ERR_PTR (- EAFNOSUPPORT );
1742
1809
#endif
1810
+ if (!info -> attrs [GTPA_PEER_ADDRESS ] &&
1811
+ !info -> attrs [GTPA_PEER_ADDR6 ])
1812
+ return ERR_PTR (- EINVAL );
1743
1813
1744
1814
if ((info -> attrs [GTPA_PEER_ADDRESS ] &&
1745
1815
sk -> sk_family == AF_INET6 ) ||
@@ -1750,9 +1820,7 @@ static struct pdp_ctx *gtp_pdp_add(struct gtp_dev *gtp, struct sock *sk,
1750
1820
switch (family ) {
1751
1821
case AF_INET :
1752
1822
if (!info -> attrs [GTPA_MS_ADDRESS ] ||
1753
- !info -> attrs [GTPA_PEER_ADDRESS ] ||
1754
- info -> attrs [GTPA_MS_ADDR6 ] ||
1755
- info -> attrs [GTPA_PEER_ADDR6 ])
1823
+ info -> attrs [GTPA_MS_ADDR6 ])
1756
1824
return ERR_PTR (- EINVAL );
1757
1825
1758
1826
ms_addr = nla_get_be32 (info -> attrs [GTPA_MS_ADDRESS ]);
@@ -1761,9 +1829,7 @@ static struct pdp_ctx *gtp_pdp_add(struct gtp_dev *gtp, struct sock *sk,
1761
1829
break ;
1762
1830
case AF_INET6 :
1763
1831
if (!info -> attrs [GTPA_MS_ADDR6 ] ||
1764
- !info -> attrs [GTPA_PEER_ADDR6 ] ||
1765
- info -> attrs [GTPA_MS_ADDRESS ] ||
1766
- info -> attrs [GTPA_PEER_ADDRESS ])
1832
+ info -> attrs [GTPA_MS_ADDRESS ])
1767
1833
return ERR_PTR (- EINVAL );
1768
1834
1769
1835
ms_addr6 = nla_get_in6_addr (info -> attrs [GTPA_MS_ADDR6 ]);
@@ -1827,8 +1893,7 @@ static struct pdp_ctx *gtp_pdp_add(struct gtp_dev *gtp, struct sock *sk,
1827
1893
1828
1894
switch (pctx -> af ) {
1829
1895
case AF_INET :
1830
- if (!info -> attrs [GTPA_MS_ADDRESS ] ||
1831
- !info -> attrs [GTPA_PEER_ADDRESS ]) {
1896
+ if (!info -> attrs [GTPA_MS_ADDRESS ]) {
1832
1897
sock_put (sk );
1833
1898
kfree (pctx );
1834
1899
return ERR_PTR (- EINVAL );
@@ -1837,8 +1902,7 @@ static struct pdp_ctx *gtp_pdp_add(struct gtp_dev *gtp, struct sock *sk,
1837
1902
ipv4_pdp_fill (pctx , info );
1838
1903
break ;
1839
1904
case AF_INET6 :
1840
- if (!info -> attrs [GTPA_MS_ADDR6 ] ||
1841
- !info -> attrs [GTPA_PEER_ADDR6 ]) {
1905
+ if (!info -> attrs [GTPA_MS_ADDR6 ]) {
1842
1906
sock_put (sk );
1843
1907
kfree (pctx );
1844
1908
return ERR_PTR (- EINVAL );
@@ -2062,13 +2126,22 @@ static int gtp_genl_fill_info(struct sk_buff *skb, u32 snd_portid, u32 snd_seq,
2062
2126
2063
2127
switch (pctx -> af ) {
2064
2128
case AF_INET :
2065
- if (nla_put_be32 (skb , GTPA_PEER_ADDRESS , pctx -> peer .addr .s_addr ) ||
2066
- nla_put_be32 (skb , GTPA_MS_ADDRESS , pctx -> ms .addr .s_addr ))
2129
+ if (nla_put_be32 (skb , GTPA_MS_ADDRESS , pctx -> ms .addr .s_addr ))
2130
+ goto nla_put_failure ;
2131
+ break ;
2132
+ case AF_INET6 :
2133
+ if (nla_put_in6_addr (skb , GTPA_MS_ADDR6 , & pctx -> ms .addr6 ))
2134
+ goto nla_put_failure ;
2135
+ break ;
2136
+ }
2137
+
2138
+ switch (pctx -> sk -> sk_family ) {
2139
+ case AF_INET :
2140
+ if (nla_put_be32 (skb , GTPA_PEER_ADDRESS , pctx -> peer .addr .s_addr ))
2067
2141
goto nla_put_failure ;
2068
2142
break ;
2069
2143
case AF_INET6 :
2070
- if (nla_put_in6_addr (skb , GTPA_PEER_ADDR6 , & pctx -> peer .addr6 ) ||
2071
- nla_put_in6_addr (skb , GTPA_MS_ADDR6 , & pctx -> ms .addr6 ))
2144
+ if (nla_put_in6_addr (skb , GTPA_PEER_ADDR6 , & pctx -> peer .addr6 ))
2072
2145
goto nla_put_failure ;
2073
2146
break ;
2074
2147
}
0 commit comments