.. | .. |
---|
12 | 12 | #include <linux/err.h> |
---|
13 | 13 | #include <linux/kernel.h> |
---|
14 | 14 | #include <linux/inetdevice.h> |
---|
15 | | -#include <linux/if_tunnel.h> |
---|
16 | 15 | #include <net/dst.h> |
---|
17 | 16 | #include <net/xfrm.h> |
---|
18 | 17 | #include <net/ip.h> |
---|
19 | 18 | #include <net/l3mdev.h> |
---|
20 | | -#include <net/inet_ecn.h> |
---|
21 | 19 | |
---|
22 | 20 | static struct dst_entry *__xfrm4_dst_lookup(struct net *net, struct flowi4 *fl4, |
---|
23 | 21 | int tos, int oif, |
---|
.. | .. |
---|
70 | 68 | return 0; |
---|
71 | 69 | } |
---|
72 | 70 | |
---|
73 | | -static int xfrm4_get_tos(const struct flowi *fl) |
---|
74 | | -{ |
---|
75 | | - return IPTOS_RT_MASK & fl->u.ip4.flowi4_tos; /* Strip ECN bits */ |
---|
76 | | -} |
---|
77 | | - |
---|
78 | | -static int xfrm4_init_path(struct xfrm_dst *path, struct dst_entry *dst, |
---|
79 | | - int nfheader_len) |
---|
80 | | -{ |
---|
81 | | - return 0; |
---|
82 | | -} |
---|
83 | | - |
---|
84 | 71 | static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev, |
---|
85 | 72 | const struct flowi *fl) |
---|
86 | 73 | { |
---|
.. | .. |
---|
98 | 85 | xdst->u.rt.rt_flags = rt->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST | |
---|
99 | 86 | RTCF_LOCAL); |
---|
100 | 87 | xdst->u.rt.rt_type = rt->rt_type; |
---|
101 | | - xdst->u.rt.rt_gateway = rt->rt_gateway; |
---|
102 | 88 | xdst->u.rt.rt_uses_gateway = rt->rt_uses_gateway; |
---|
| 89 | + xdst->u.rt.rt_gw_family = rt->rt_gw_family; |
---|
| 90 | + if (rt->rt_gw_family == AF_INET) |
---|
| 91 | + xdst->u.rt.rt_gw4 = rt->rt_gw4; |
---|
| 92 | + else if (rt->rt_gw_family == AF_INET6) |
---|
| 93 | + xdst->u.rt.rt_gw6 = rt->rt_gw6; |
---|
103 | 94 | xdst->u.rt.rt_pmtu = rt->rt_pmtu; |
---|
104 | 95 | xdst->u.rt.rt_mtu_locked = rt->rt_mtu_locked; |
---|
105 | 96 | INIT_LIST_HEAD(&xdst->u.rt.rt_uncached); |
---|
106 | 97 | rt_add_uncached_list(&xdst->u.rt); |
---|
107 | 98 | |
---|
108 | 99 | return 0; |
---|
109 | | -} |
---|
110 | | - |
---|
111 | | -static void |
---|
112 | | -_decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse) |
---|
113 | | -{ |
---|
114 | | - const struct iphdr *iph = ip_hdr(skb); |
---|
115 | | - int ihl = iph->ihl; |
---|
116 | | - u8 *xprth = skb_network_header(skb) + ihl * 4; |
---|
117 | | - struct flowi4 *fl4 = &fl->u.ip4; |
---|
118 | | - int oif = 0; |
---|
119 | | - |
---|
120 | | - if (skb_dst(skb)) |
---|
121 | | - oif = skb_dst(skb)->dev->ifindex; |
---|
122 | | - |
---|
123 | | - memset(fl4, 0, sizeof(struct flowi4)); |
---|
124 | | - fl4->flowi4_mark = skb->mark; |
---|
125 | | - fl4->flowi4_oif = reverse ? skb->skb_iif : oif; |
---|
126 | | - |
---|
127 | | - fl4->flowi4_proto = iph->protocol; |
---|
128 | | - fl4->daddr = reverse ? iph->saddr : iph->daddr; |
---|
129 | | - fl4->saddr = reverse ? iph->daddr : iph->saddr; |
---|
130 | | - fl4->flowi4_tos = iph->tos & ~INET_ECN_MASK; |
---|
131 | | - |
---|
132 | | - if (!ip_is_fragment(iph)) { |
---|
133 | | - switch (iph->protocol) { |
---|
134 | | - case IPPROTO_UDP: |
---|
135 | | - case IPPROTO_UDPLITE: |
---|
136 | | - case IPPROTO_TCP: |
---|
137 | | - case IPPROTO_SCTP: |
---|
138 | | - case IPPROTO_DCCP: |
---|
139 | | - if (xprth + 4 < skb->data || |
---|
140 | | - pskb_may_pull(skb, xprth + 4 - skb->data)) { |
---|
141 | | - __be16 *ports; |
---|
142 | | - |
---|
143 | | - xprth = skb_network_header(skb) + ihl * 4; |
---|
144 | | - ports = (__be16 *)xprth; |
---|
145 | | - |
---|
146 | | - fl4->fl4_sport = ports[!!reverse]; |
---|
147 | | - fl4->fl4_dport = ports[!reverse]; |
---|
148 | | - } |
---|
149 | | - break; |
---|
150 | | - |
---|
151 | | - case IPPROTO_ICMP: |
---|
152 | | - if (xprth + 2 < skb->data || |
---|
153 | | - pskb_may_pull(skb, xprth + 2 - skb->data)) { |
---|
154 | | - u8 *icmp; |
---|
155 | | - |
---|
156 | | - xprth = skb_network_header(skb) + ihl * 4; |
---|
157 | | - icmp = xprth; |
---|
158 | | - |
---|
159 | | - fl4->fl4_icmp_type = icmp[0]; |
---|
160 | | - fl4->fl4_icmp_code = icmp[1]; |
---|
161 | | - } |
---|
162 | | - break; |
---|
163 | | - |
---|
164 | | - case IPPROTO_ESP: |
---|
165 | | - if (xprth + 4 < skb->data || |
---|
166 | | - pskb_may_pull(skb, xprth + 4 - skb->data)) { |
---|
167 | | - __be32 *ehdr; |
---|
168 | | - |
---|
169 | | - xprth = skb_network_header(skb) + ihl * 4; |
---|
170 | | - ehdr = (__be32 *)xprth; |
---|
171 | | - |
---|
172 | | - fl4->fl4_ipsec_spi = ehdr[0]; |
---|
173 | | - } |
---|
174 | | - break; |
---|
175 | | - |
---|
176 | | - case IPPROTO_AH: |
---|
177 | | - if (xprth + 8 < skb->data || |
---|
178 | | - pskb_may_pull(skb, xprth + 8 - skb->data)) { |
---|
179 | | - __be32 *ah_hdr; |
---|
180 | | - |
---|
181 | | - xprth = skb_network_header(skb) + ihl * 4; |
---|
182 | | - ah_hdr = (__be32 *)xprth; |
---|
183 | | - |
---|
184 | | - fl4->fl4_ipsec_spi = ah_hdr[1]; |
---|
185 | | - } |
---|
186 | | - break; |
---|
187 | | - |
---|
188 | | - case IPPROTO_COMP: |
---|
189 | | - if (xprth + 4 < skb->data || |
---|
190 | | - pskb_may_pull(skb, xprth + 4 - skb->data)) { |
---|
191 | | - __be16 *ipcomp_hdr; |
---|
192 | | - |
---|
193 | | - xprth = skb_network_header(skb) + ihl * 4; |
---|
194 | | - ipcomp_hdr = (__be16 *)xprth; |
---|
195 | | - |
---|
196 | | - fl4->fl4_ipsec_spi = htonl(ntohs(ipcomp_hdr[1])); |
---|
197 | | - } |
---|
198 | | - break; |
---|
199 | | - |
---|
200 | | - case IPPROTO_GRE: |
---|
201 | | - if (xprth + 12 < skb->data || |
---|
202 | | - pskb_may_pull(skb, xprth + 12 - skb->data)) { |
---|
203 | | - __be16 *greflags; |
---|
204 | | - __be32 *gre_hdr; |
---|
205 | | - |
---|
206 | | - xprth = skb_network_header(skb) + ihl * 4; |
---|
207 | | - greflags = (__be16 *)xprth; |
---|
208 | | - gre_hdr = (__be32 *)xprth; |
---|
209 | | - |
---|
210 | | - if (greflags[0] & GRE_KEY) { |
---|
211 | | - if (greflags[0] & GRE_CSUM) |
---|
212 | | - gre_hdr++; |
---|
213 | | - fl4->fl4_gre_key = gre_hdr[1]; |
---|
214 | | - } |
---|
215 | | - } |
---|
216 | | - break; |
---|
217 | | - |
---|
218 | | - default: |
---|
219 | | - fl4->fl4_ipsec_spi = 0; |
---|
220 | | - break; |
---|
221 | | - } |
---|
222 | | - } |
---|
223 | 100 | } |
---|
224 | 101 | |
---|
225 | 102 | static void xfrm4_update_pmtu(struct dst_entry *dst, struct sock *sk, |
---|
.. | .. |
---|
275 | 152 | .dst_ops = &xfrm4_dst_ops_template, |
---|
276 | 153 | .dst_lookup = xfrm4_dst_lookup, |
---|
277 | 154 | .get_saddr = xfrm4_get_saddr, |
---|
278 | | - .decode_session = _decode_session4, |
---|
279 | | - .get_tos = xfrm4_get_tos, |
---|
280 | | - .init_path = xfrm4_init_path, |
---|
281 | 155 | .fill_dst = xfrm4_fill_dst, |
---|
282 | 156 | .blackhole_route = ipv4_blackhole_route, |
---|
283 | 157 | }; |
---|