hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/net/ipv6/xfrm6_input.c
....@@ -17,11 +17,6 @@
1717 #include <net/ipv6.h>
1818 #include <net/xfrm.h>
1919
20
-int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb)
21
-{
22
- return xfrm6_extract_header(skb);
23
-}
24
-
2520 int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi,
2621 struct ip6_tnl *t)
2722 {
....@@ -35,9 +30,12 @@
3530 static int xfrm6_transport_finish2(struct net *net, struct sock *sk,
3631 struct sk_buff *skb)
3732 {
38
- if (xfrm_trans_queue(skb, ip6_rcv_finish))
39
- __kfree_skb(skb);
40
- return -1;
33
+ if (xfrm_trans_queue(skb, ip6_rcv_finish)) {
34
+ kfree_skb(skb);
35
+ return NET_RX_DROP;
36
+ }
37
+
38
+ return 0;
4139 }
4240
4341 int xfrm6_transport_finish(struct sk_buff *skb, int async)
....@@ -60,13 +58,109 @@
6058 if (xo && (xo->flags & XFRM_GRO)) {
6159 skb_mac_header_rebuild(skb);
6260 skb_reset_transport_header(skb);
63
- return -1;
61
+ return 0;
6462 }
6563
6664 NF_HOOK(NFPROTO_IPV6, NF_INET_PRE_ROUTING,
6765 dev_net(skb->dev), NULL, skb, skb->dev, NULL,
6866 xfrm6_transport_finish2);
69
- return -1;
67
+ return 0;
68
+}
69
+
70
+/* If it's a keepalive packet, then just eat it.
71
+ * If it's an encapsulated packet, then pass it to the
72
+ * IPsec xfrm input.
73
+ * Returns 0 if skb passed to xfrm or was dropped.
74
+ * Returns >0 if skb should be passed to UDP.
75
+ * Returns <0 if skb should be resubmitted (-ret is protocol)
76
+ */
77
+int xfrm6_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)
78
+{
79
+ struct udp_sock *up = udp_sk(sk);
80
+ struct udphdr *uh;
81
+ struct ipv6hdr *ip6h;
82
+ int len;
83
+ int ip6hlen = sizeof(struct ipv6hdr);
84
+
85
+ __u8 *udpdata;
86
+ __be32 *udpdata32;
87
+ __u16 encap_type = up->encap_type;
88
+
89
+ if (skb->protocol == htons(ETH_P_IP))
90
+ return xfrm4_udp_encap_rcv(sk, skb);
91
+
92
+ /* if this is not encapsulated socket, then just return now */
93
+ if (!encap_type)
94
+ return 1;
95
+
96
+ /* If this is a paged skb, make sure we pull up
97
+ * whatever data we need to look at. */
98
+ len = skb->len - sizeof(struct udphdr);
99
+ if (!pskb_may_pull(skb, sizeof(struct udphdr) + min(len, 8)))
100
+ return 1;
101
+
102
+ /* Now we can get the pointers */
103
+ uh = udp_hdr(skb);
104
+ udpdata = (__u8 *)uh + sizeof(struct udphdr);
105
+ udpdata32 = (__be32 *)udpdata;
106
+
107
+ switch (encap_type) {
108
+ default:
109
+ case UDP_ENCAP_ESPINUDP:
110
+ /* Check if this is a keepalive packet. If so, eat it. */
111
+ if (len == 1 && udpdata[0] == 0xff) {
112
+ goto drop;
113
+ } else if (len > sizeof(struct ip_esp_hdr) && udpdata32[0] != 0) {
114
+ /* ESP Packet without Non-ESP header */
115
+ len = sizeof(struct udphdr);
116
+ } else
117
+ /* Must be an IKE packet.. pass it through */
118
+ return 1;
119
+ break;
120
+ case UDP_ENCAP_ESPINUDP_NON_IKE:
121
+ /* Check if this is a keepalive packet. If so, eat it. */
122
+ if (len == 1 && udpdata[0] == 0xff) {
123
+ goto drop;
124
+ } else if (len > 2 * sizeof(u32) + sizeof(struct ip_esp_hdr) &&
125
+ udpdata32[0] == 0 && udpdata32[1] == 0) {
126
+
127
+ /* ESP Packet with Non-IKE marker */
128
+ len = sizeof(struct udphdr) + 2 * sizeof(u32);
129
+ } else
130
+ /* Must be an IKE packet.. pass it through */
131
+ return 1;
132
+ break;
133
+ }
134
+
135
+ /* At this point we are sure that this is an ESPinUDP packet,
136
+ * so we need to remove 'len' bytes from the packet (the UDP
137
+ * header and optional ESP marker bytes) and then modify the
138
+ * protocol to ESP, and then call into the transform receiver.
139
+ */
140
+ if (skb_unclone(skb, GFP_ATOMIC))
141
+ goto drop;
142
+
143
+ /* Now we can update and verify the packet length... */
144
+ ip6h = ipv6_hdr(skb);
145
+ ip6h->payload_len = htons(ntohs(ip6h->payload_len) - len);
146
+ if (skb->len < ip6hlen + len) {
147
+ /* packet is too small!?! */
148
+ goto drop;
149
+ }
150
+
151
+ /* pull the data buffer up to the ESP header and set the
152
+ * transport header to point to ESP. Keep UDP on the stack
153
+ * for later.
154
+ */
155
+ __skb_pull(skb, len);
156
+ skb_reset_transport_header(skb);
157
+
158
+ /* process ESP */
159
+ return xfrm6_rcv_encap(skb, IPPROTO_ESP, 0, encap_type);
160
+
161
+drop:
162
+ kfree_skb(skb);
163
+ return 0;
70164 }
71165
72166 int xfrm6_rcv_tnl(struct sk_buff *skb, struct ip6_tnl *t)
....@@ -86,14 +180,16 @@
86180 {
87181 struct net *net = dev_net(skb->dev);
88182 struct xfrm_state *x = NULL;
183
+ struct sec_path *sp;
89184 int i = 0;
90185
91
- if (secpath_set(skb)) {
186
+ sp = secpath_set(skb);
187
+ if (!sp) {
92188 XFRM_INC_STATS(net, LINUX_MIB_XFRMINERROR);
93189 goto drop;
94190 }
95191
96
- if (1 + skb->sp->len == XFRM_MAX_DEPTH) {
192
+ if (1 + sp->len == XFRM_MAX_DEPTH) {
97193 XFRM_INC_STATS(net, LINUX_MIB_XFRMINBUFFERERROR);
98194 goto drop;
99195 }
....@@ -145,7 +241,7 @@
145241 goto drop;
146242 }
147243
148
- skb->sp->xvec[skb->sp->len++] = x;
244
+ sp->xvec[sp->len++] = x;
149245
150246 spin_lock(&x->lock);
151247