@@ -983,33 +983,16 @@ static void gtp_set_pktinfo_ipv6(struct gtp_pktinfo *pktinfo,
983
983
pktinfo -> dev = dev ;
984
984
}
985
985
986
- static int gtp_build_skb_ip4 (struct sk_buff * skb , struct net_device * dev ,
987
- struct gtp_pktinfo * pktinfo )
986
+ static int gtp_build_skb_outer_ip4 (struct sk_buff * skb , struct net_device * dev ,
987
+ struct gtp_pktinfo * pktinfo ,
988
+ struct pdp_ctx * pctx , __u8 tos ,
989
+ __be16 frag_off )
988
990
{
989
- struct gtp_dev * gtp = netdev_priv (dev );
990
- struct pdp_ctx * pctx ;
991
991
struct rtable * rt ;
992
992
struct flowi4 fl4 ;
993
- struct iphdr * iph ;
994
993
__be16 df ;
995
994
int mtu ;
996
995
997
- /* Read the IP destination address and resolve the PDP context.
998
- * Prepend PDP header with TEI/TID from PDP ctx.
999
- */
1000
- iph = ip_hdr (skb );
1001
- if (gtp -> role == GTP_ROLE_SGSN )
1002
- pctx = ipv4_pdp_find (gtp , iph -> saddr );
1003
- else
1004
- pctx = ipv4_pdp_find (gtp , iph -> daddr );
1005
-
1006
- if (!pctx ) {
1007
- netdev_dbg (dev , "no PDP ctx found for %pI4, skip\n" ,
1008
- & iph -> daddr );
1009
- return - ENOENT ;
1010
- }
1011
- netdev_dbg (dev , "found PDP context %p\n" , pctx );
1012
-
1013
996
rt = ip4_route_output_gtp (& fl4 , pctx -> sk , pctx -> peer .addr .s_addr ,
1014
997
inet_sk (pctx -> sk )-> inet_saddr );
1015
998
if (IS_ERR (rt )) {
@@ -1027,7 +1010,7 @@ static int gtp_build_skb_ip4(struct sk_buff *skb, struct net_device *dev,
1027
1010
}
1028
1011
1029
1012
/* This is similar to tnl_update_pmtu(). */
1030
- df = iph -> frag_off ;
1013
+ df = frag_off ;
1031
1014
if (df ) {
1032
1015
mtu = dst_mtu (& rt -> dst ) - dev -> hard_header_len -
1033
1016
sizeof (struct iphdr ) - sizeof (struct udphdr );
@@ -1045,7 +1028,7 @@ static int gtp_build_skb_ip4(struct sk_buff *skb, struct net_device *dev,
1045
1028
1046
1029
skb_dst_update_pmtu_no_confirm (skb , mtu );
1047
1030
1048
- if (iph -> frag_off & htons (IP_DF ) &&
1031
+ if (frag_off & htons (IP_DF ) &&
1049
1032
((!skb_is_gso (skb ) && skb -> len > mtu ) ||
1050
1033
(skb_is_gso (skb ) && !skb_gso_validate_network_len (skb , mtu )))) {
1051
1034
netdev_dbg (dev , "packet too big, fragmentation needed\n" );
@@ -1054,19 +1037,51 @@ static int gtp_build_skb_ip4(struct sk_buff *skb, struct net_device *dev,
1054
1037
goto err_rt ;
1055
1038
}
1056
1039
1057
- gtp_set_pktinfo_ipv4 (pktinfo , pctx -> sk , iph -> tos , pctx , rt , & fl4 , dev );
1040
+ gtp_set_pktinfo_ipv4 (pktinfo , pctx -> sk , tos , pctx , rt , & fl4 , dev );
1058
1041
gtp_push_header (skb , pktinfo );
1059
1042
1060
- netdev_dbg (dev , "gtp -> IP src: %pI4 dst: %pI4\n" ,
1061
- & iph -> saddr , & iph -> daddr );
1062
-
1063
1043
return 0 ;
1064
1044
err_rt :
1065
1045
ip_rt_put (rt );
1066
1046
err :
1067
1047
return - EBADMSG ;
1068
1048
}
1069
1049
1050
+ static int gtp_build_skb_ip4 (struct sk_buff * skb , struct net_device * dev ,
1051
+ struct gtp_pktinfo * pktinfo )
1052
+ {
1053
+ struct gtp_dev * gtp = netdev_priv (dev );
1054
+ struct pdp_ctx * pctx ;
1055
+ struct iphdr * iph ;
1056
+ int ret ;
1057
+
1058
+ /* Read the IP destination address and resolve the PDP context.
1059
+ * Prepend PDP header with TEI/TID from PDP ctx.
1060
+ */
1061
+ iph = ip_hdr (skb );
1062
+ if (gtp -> role == GTP_ROLE_SGSN )
1063
+ pctx = ipv4_pdp_find (gtp , iph -> saddr );
1064
+ else
1065
+ pctx = ipv4_pdp_find (gtp , iph -> daddr );
1066
+
1067
+ if (!pctx ) {
1068
+ netdev_dbg (dev , "no PDP ctx found for %pI4, skip\n" ,
1069
+ & iph -> daddr );
1070
+ return - ENOENT ;
1071
+ }
1072
+ netdev_dbg (dev , "found PDP context %p\n" , pctx );
1073
+
1074
+ ret = gtp_build_skb_outer_ip4 (skb , dev , pktinfo , pctx ,
1075
+ iph -> tos , iph -> frag_off );
1076
+ if (ret < 0 )
1077
+ return ret ;
1078
+
1079
+ netdev_dbg (dev , "gtp -> IP src: %pI4 dst: %pI4\n" ,
1080
+ & iph -> saddr , & iph -> daddr );
1081
+
1082
+ return 0 ;
1083
+ }
1084
+
1070
1085
static int gtp_build_skb_ip6 (struct sk_buff * skb , struct net_device * dev ,
1071
1086
struct gtp_pktinfo * pktinfo )
1072
1087
{
0 commit comments