|
70 | 70 | * Alexey Kuznetsov: allow both IPv4 and IPv6 sockets to bind |
71 | 71 | * a single port at the same time. |
72 | 72 | * Derek Atkins <[email protected]>: Add Encapulation Support |
| 73 | + * James Chapman : Add L2TP encapsulation type. |
73 | 74 | * |
74 | 75 | * |
75 | 76 | * This program is free software; you can redistribute it and/or |
@@ -923,12 +924,10 @@ int udp_disconnect(struct sock *sk, int flags) |
923 | 924 | * 1 if the UDP system should process it |
924 | 925 | * 0 if we should drop this packet |
925 | 926 | * -1 if it should get processed by xfrm4_rcv_encap |
| 927 | + * -2 if it should get processed by l2tp |
926 | 928 | */ |
927 | 929 | static int udp_encap_rcv(struct sock * sk, struct sk_buff *skb) |
928 | 930 | { |
929 | | -#ifndef CONFIG_XFRM |
930 | | - return 1; |
931 | | -#else |
932 | 931 | struct udp_sock *up = udp_sk(sk); |
933 | 932 | struct udphdr *uh; |
934 | 933 | struct iphdr *iph; |
@@ -983,8 +982,14 @@ static int udp_encap_rcv(struct sock * sk, struct sk_buff *skb) |
983 | 982 | /* Must be an IKE packet.. pass it through */ |
984 | 983 | return 1; |
985 | 984 | break; |
| 985 | + case UDP_ENCAP_L2TPINUDP: |
| 986 | + /* Let caller know to send this to l2tp */ |
| 987 | + return -2; |
986 | 988 | } |
987 | 989 |
|
| 990 | +#ifndef CONFIG_XFRM |
| 991 | + return 1; |
| 992 | +#else |
988 | 993 | /* At this point we are sure that this is an ESPinUDP packet, |
989 | 994 | * so we need to remove 'len' bytes from the packet (the UDP |
990 | 995 | * header and optional ESP marker bytes) and then modify the |
@@ -1055,12 +1060,25 @@ int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb) |
1055 | 1060 | kfree_skb(skb); |
1056 | 1061 | return 0; |
1057 | 1062 | } |
1058 | | - if (ret < 0) { |
| 1063 | + if (ret == -1) { |
1059 | 1064 | /* process the ESP packet */ |
1060 | 1065 | ret = xfrm4_rcv_encap(skb, up->encap_type); |
1061 | 1066 | UDP_INC_STATS_BH(UDP_MIB_INDATAGRAMS, up->pcflag); |
1062 | 1067 | return -ret; |
1063 | 1068 | } |
| 1069 | + if (ret == -2) { |
| 1070 | + /* process the L2TP packet */ |
| 1071 | + if (up->encap_rcv != NULL) { |
| 1072 | + ret = (*up->encap_rcv)(sk, skb); |
| 1073 | + if (ret <= 0) { |
| 1074 | + UDP_INC_STATS_BH(UDP_MIB_INDATAGRAMS, up->pcflag); |
| 1075 | + return ret; |
| 1076 | + } |
| 1077 | + |
| 1078 | + /* FALLTHROUGH -- pass up as UDP packet */ |
| 1079 | + } |
| 1080 | + } |
| 1081 | + |
1064 | 1082 | /* FALLTHROUGH -- it's a UDP Packet */ |
1065 | 1083 | } |
1066 | 1084 |
|
@@ -1349,6 +1367,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname, |
1349 | 1367 | case 0: |
1350 | 1368 | case UDP_ENCAP_ESPINUDP: |
1351 | 1369 | case UDP_ENCAP_ESPINUDP_NON_IKE: |
| 1370 | + case UDP_ENCAP_L2TPINUDP: |
1352 | 1371 | up->encap_type = val; |
1353 | 1372 | break; |
1354 | 1373 | default: |
|
0 commit comments