OpenWrt – Diff between revs 2 and 3
?pathlinks?
Rev 2 | Rev 3 | |||
---|---|---|---|---|
1 | From: Jonas Gorski <jogo@openwrt.org> |
1 | From: Jonas Gorski <jogo@openwrt.org> |
|
2 | Subject: ipv6: allow rejecting with "source address failed policy" |
2 | Subject: ipv6: allow rejecting with "source address failed policy" |
|
3 | |
3 | |
|
4 | RFC6204 L-14 requires rejecting traffic from invalid addresses with |
4 | RFC6204 L-14 requires rejecting traffic from invalid addresses with |
|
5 | ICMPv6 Destination Unreachable, Code 5 (Source address failed ingress/ |
5 | ICMPv6 Destination Unreachable, Code 5 (Source address failed ingress/ |
|
6 | egress policy) on the LAN side, so add an appropriate rule for that. |
6 | egress policy) on the LAN side, so add an appropriate rule for that. |
|
7 | |
7 | |
|
8 | Signed-off-by: Jonas Gorski <jogo@openwrt.org> |
8 | Signed-off-by: Jonas Gorski <jogo@openwrt.org> |
|
9 | --- |
9 | --- |
|
10 | include/net/netns/ipv6.h | 1 + |
10 | include/net/netns/ipv6.h | 1 + |
|
11 | include/uapi/linux/fib_rules.h | 4 +++ |
11 | include/uapi/linux/fib_rules.h | 4 +++ |
|
12 | include/uapi/linux/rtnetlink.h | 1 + |
12 | include/uapi/linux/rtnetlink.h | 1 + |
|
13 | net/ipv4/fib_semantics.c | 4 +++ |
13 | net/ipv4/fib_semantics.c | 4 +++ |
|
14 | net/ipv4/fib_trie.c | 1 + |
14 | net/ipv4/fib_trie.c | 1 + |
|
15 | net/ipv4/ipmr.c | 1 + |
15 | net/ipv4/ipmr.c | 1 + |
|
16 | net/ipv6/fib6_rules.c | 4 +++ |
16 | net/ipv6/fib6_rules.c | 4 +++ |
|
17 | net/ipv6/ip6mr.c | 2 ++ |
17 | net/ipv6/ip6mr.c | 2 ++ |
|
18 | net/ipv6/route.c | 58 +++++++++++++++++++++++++++++++++++++++++- |
18 | net/ipv6/route.c | 58 +++++++++++++++++++++++++++++++++++++++++- |
|
19 | 9 files changed, 75 insertions(+), 1 deletion(-) |
19 | 9 files changed, 75 insertions(+), 1 deletion(-) |
|
20 | |
20 | |
|
21 | --- a/include/net/netns/ipv6.h |
21 | --- a/include/net/netns/ipv6.h |
|
22 | +++ b/include/net/netns/ipv6.h |
22 | +++ b/include/net/netns/ipv6.h |
|
23 | @@ -69,6 +69,7 @@ struct netns_ipv6 { |
23 | @@ -69,6 +69,7 @@ struct netns_ipv6 { |
|
24 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES |
24 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES |
|
25 | bool fib6_has_custom_rules; |
25 | bool fib6_has_custom_rules; |
|
26 | struct rt6_info *ip6_prohibit_entry; |
26 | struct rt6_info *ip6_prohibit_entry; |
|
27 | + struct rt6_info *ip6_policy_failed_entry; |
27 | + struct rt6_info *ip6_policy_failed_entry; |
|
28 | struct rt6_info *ip6_blk_hole_entry; |
28 | struct rt6_info *ip6_blk_hole_entry; |
|
29 | struct fib6_table *fib6_local_tbl; |
29 | struct fib6_table *fib6_local_tbl; |
|
30 | struct fib_rules_ops *fib6_rules_ops; |
30 | struct fib_rules_ops *fib6_rules_ops; |
|
31 | --- a/include/uapi/linux/fib_rules.h |
31 | --- a/include/uapi/linux/fib_rules.h |
|
32 | +++ b/include/uapi/linux/fib_rules.h |
32 | +++ b/include/uapi/linux/fib_rules.h |
|
33 | @@ -73,6 +73,10 @@ enum { |
33 | @@ -73,6 +73,10 @@ enum { |
|
34 | FR_ACT_BLACKHOLE, /* Drop without notification */ |
34 | FR_ACT_BLACKHOLE, /* Drop without notification */ |
|
35 | FR_ACT_UNREACHABLE, /* Drop with ENETUNREACH */ |
35 | FR_ACT_UNREACHABLE, /* Drop with ENETUNREACH */ |
|
36 | FR_ACT_PROHIBIT, /* Drop with EACCES */ |
36 | FR_ACT_PROHIBIT, /* Drop with EACCES */ |
|
37 | + FR_ACT_RES9, |
37 | + FR_ACT_RES9, |
|
38 | + FR_ACT_RES10, |
38 | + FR_ACT_RES10, |
|
39 | + FR_ACT_RES11, |
39 | + FR_ACT_RES11, |
|
40 | + FR_ACT_POLICY_FAILED, /* Drop with EACCES */ |
40 | + FR_ACT_POLICY_FAILED, /* Drop with EACCES */ |
|
41 | __FR_ACT_MAX, |
41 | __FR_ACT_MAX, |
|
42 | }; |
42 | }; |
|
43 | |
43 | |
|
44 | --- a/include/uapi/linux/rtnetlink.h |
44 | --- a/include/uapi/linux/rtnetlink.h |
|
45 | +++ b/include/uapi/linux/rtnetlink.h |
45 | +++ b/include/uapi/linux/rtnetlink.h |
|
46 | @@ -221,6 +221,7 @@ enum { |
46 | @@ -221,6 +221,7 @@ enum { |
|
47 | RTN_THROW, /* Not in this table */ |
47 | RTN_THROW, /* Not in this table */ |
|
48 | RTN_NAT, /* Translate this address */ |
48 | RTN_NAT, /* Translate this address */ |
|
49 | RTN_XRESOLVE, /* Use external resolver */ |
49 | RTN_XRESOLVE, /* Use external resolver */ |
|
50 | + RTN_POLICY_FAILED, /* Failed ingress/egress policy */ |
50 | + RTN_POLICY_FAILED, /* Failed ingress/egress policy */ |
|
51 | __RTN_MAX |
51 | __RTN_MAX |
|
52 | }; |
52 | }; |
|
53 | |
53 | |
|
54 | --- a/net/ipv4/fib_semantics.c |
54 | --- a/net/ipv4/fib_semantics.c |
|
55 | +++ b/net/ipv4/fib_semantics.c |
55 | +++ b/net/ipv4/fib_semantics.c |
|
56 | @@ -139,6 +139,10 @@ const struct fib_prop fib_props[RTN_MAX |
56 | @@ -139,6 +139,10 @@ const struct fib_prop fib_props[RTN_MAX |
|
57 | .error = -EINVAL, |
57 | .error = -EINVAL, |
|
58 | .scope = RT_SCOPE_NOWHERE, |
58 | .scope = RT_SCOPE_NOWHERE, |
|
59 | }, |
59 | }, |
|
60 | + [RTN_POLICY_FAILED] = { |
60 | + [RTN_POLICY_FAILED] = { |
|
61 | + .error = -EACCES, |
61 | + .error = -EACCES, |
|
62 | + .scope = RT_SCOPE_UNIVERSE, |
62 | + .scope = RT_SCOPE_UNIVERSE, |
|
63 | + }, |
63 | + }, |
|
64 | }; |
64 | }; |
|
65 | |
65 | |
|
66 | static void rt_fibinfo_free(struct rtable __rcu **rtp) |
66 | static void rt_fibinfo_free(struct rtable __rcu **rtp) |
|
67 | --- a/net/ipv4/fib_trie.c |
67 | --- a/net/ipv4/fib_trie.c |
|
68 | +++ b/net/ipv4/fib_trie.c |
68 | +++ b/net/ipv4/fib_trie.c |
|
69 | @@ -2469,6 +2469,7 @@ static const char *const rtn_type_names[ |
69 | @@ -2460,6 +2460,7 @@ static const char *const rtn_type_names[ |
|
70 | [RTN_THROW] = "THROW", |
70 | [RTN_THROW] = "THROW", |
|
71 | [RTN_NAT] = "NAT", |
71 | [RTN_NAT] = "NAT", |
|
72 | [RTN_XRESOLVE] = "XRESOLVE", |
72 | [RTN_XRESOLVE] = "XRESOLVE", |
|
73 | + [RTN_POLICY_FAILED] = "POLICY_FAILED", |
73 | + [RTN_POLICY_FAILED] = "POLICY_FAILED", |
|
74 | }; |
74 | }; |
|
75 | |
75 | |
|
76 | static inline const char *rtn_type(char *buf, size_t len, unsigned int t) |
76 | static inline const char *rtn_type(char *buf, size_t len, unsigned int t) |
|
77 | --- a/net/ipv4/ipmr.c |
77 | --- a/net/ipv4/ipmr.c |
|
78 | +++ b/net/ipv4/ipmr.c |
78 | +++ b/net/ipv4/ipmr.c |
|
79 | @@ -163,6 +163,7 @@ static int ipmr_rule_action(struct fib_r |
79 | @@ -161,6 +161,7 @@ static int ipmr_rule_action(struct fib_r |
|
80 | case FR_ACT_UNREACHABLE: |
80 | case FR_ACT_UNREACHABLE: |
|
81 | return -ENETUNREACH; |
81 | return -ENETUNREACH; |
|
82 | case FR_ACT_PROHIBIT: |
82 | case FR_ACT_PROHIBIT: |
|
83 | + case FR_ACT_POLICY_FAILED: |
83 | + case FR_ACT_POLICY_FAILED: |
|
84 | return -EACCES; |
84 | return -EACCES; |
|
85 | case FR_ACT_BLACKHOLE: |
85 | case FR_ACT_BLACKHOLE: |
|
86 | default: |
86 | default: |
|
87 | --- a/net/ipv6/fib6_rules.c |
87 | --- a/net/ipv6/fib6_rules.c |
|
88 | +++ b/net/ipv6/fib6_rules.c |
88 | +++ b/net/ipv6/fib6_rules.c |
|
89 | @@ -121,6 +121,10 @@ static int fib6_rule_action(struct fib_r |
89 | @@ -121,6 +121,10 @@ static int fib6_rule_action(struct fib_r |
|
90 | err = -EACCES; |
90 | err = -EACCES; |
|
91 | rt = net->ipv6.ip6_prohibit_entry; |
91 | rt = net->ipv6.ip6_prohibit_entry; |
|
92 | goto discard_pkt; |
92 | goto discard_pkt; |
|
93 | + case FR_ACT_POLICY_FAILED: |
93 | + case FR_ACT_POLICY_FAILED: |
|
94 | + err = -EACCES; |
94 | + err = -EACCES; |
|
95 | + rt = net->ipv6.ip6_policy_failed_entry; |
95 | + rt = net->ipv6.ip6_policy_failed_entry; |
|
96 | + goto discard_pkt; |
96 | + goto discard_pkt; |
|
97 | } |
97 | } |
|
98 | |
98 | |
|
99 | tb_id = fib_rule_get_table(rule, arg); |
99 | tb_id = fib_rule_get_table(rule, arg); |
|
100 | --- a/net/ipv6/ip6mr.c |
100 | --- a/net/ipv6/ip6mr.c |
|
101 | +++ b/net/ipv6/ip6mr.c |
101 | +++ b/net/ipv6/ip6mr.c |
|
102 | @@ -170,6 +170,8 @@ static int ip6mr_rule_action(struct fib_ |
102 | @@ -168,6 +168,8 @@ static int ip6mr_rule_action(struct fib_ |
|
103 | return -ENETUNREACH; |
103 | return -ENETUNREACH; |
|
104 | case FR_ACT_PROHIBIT: |
104 | case FR_ACT_PROHIBIT: |
|
105 | return -EACCES; |
105 | return -EACCES; |
|
106 | + case FR_ACT_POLICY_FAILED: |
106 | + case FR_ACT_POLICY_FAILED: |
|
107 | + return -EACCES; |
107 | + return -EACCES; |
|
108 | case FR_ACT_BLACKHOLE: |
108 | case FR_ACT_BLACKHOLE: |
|
109 | default: |
109 | default: |
|
110 | return -EINVAL; |
110 | return -EINVAL; |
|
111 | --- a/net/ipv6/route.c |
111 | --- a/net/ipv6/route.c |
|
112 | +++ b/net/ipv6/route.c |
112 | +++ b/net/ipv6/route.c |
|
113 | @@ -91,6 +91,8 @@ static int ip6_pkt_discard(struct sk_bu |
113 | @@ -91,6 +91,8 @@ static int ip6_pkt_discard(struct sk_bu |
|
114 | static int ip6_pkt_discard_out(struct net *net, struct sock *sk, struct sk_buff *skb); |
114 | static int ip6_pkt_discard_out(struct net *net, struct sock *sk, struct sk_buff *skb); |
|
115 | static int ip6_pkt_prohibit(struct sk_buff *skb); |
115 | static int ip6_pkt_prohibit(struct sk_buff *skb); |
|
116 | static int ip6_pkt_prohibit_out(struct net *net, struct sock *sk, struct sk_buff *skb); |
116 | static int ip6_pkt_prohibit_out(struct net *net, struct sock *sk, struct sk_buff *skb); |
|
117 | +static int ip6_pkt_policy_failed(struct sk_buff *skb); |
117 | +static int ip6_pkt_policy_failed(struct sk_buff *skb); |
|
118 | +static int ip6_pkt_policy_failed_out(struct net *net, struct sock *sk, struct sk_buff *skb); |
118 | +static int ip6_pkt_policy_failed_out(struct net *net, struct sock *sk, struct sk_buff *skb); |
|
119 | static void ip6_link_failure(struct sk_buff *skb); |
119 | static void ip6_link_failure(struct sk_buff *skb); |
|
120 | static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, |
120 | static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, |
|
121 | struct sk_buff *skb, u32 mtu); |
121 | struct sk_buff *skb, u32 mtu); |
|
122 | @@ -321,6 +323,21 @@ static const struct rt6_info ip6_prohibi |
122 | @@ -321,6 +323,21 @@ static const struct rt6_info ip6_prohibi |
|
123 | .rt6i_ref = ATOMIC_INIT(1), |
123 | .rt6i_ref = ATOMIC_INIT(1), |
|
124 | }; |
124 | }; |
|
125 | |
125 | |
|
126 | +static const struct rt6_info ip6_policy_failed_entry_template = { |
126 | +static const struct rt6_info ip6_policy_failed_entry_template = { |
|
127 | + .dst = { |
127 | + .dst = { |
|
128 | + .__refcnt = ATOMIC_INIT(1), |
128 | + .__refcnt = ATOMIC_INIT(1), |
|
129 | + .__use = 1, |
129 | + .__use = 1, |
|
130 | + .obsolete = DST_OBSOLETE_FORCE_CHK, |
130 | + .obsolete = DST_OBSOLETE_FORCE_CHK, |
|
131 | + .error = -EACCES, |
131 | + .error = -EACCES, |
|
132 | + .input = ip6_pkt_policy_failed, |
132 | + .input = ip6_pkt_policy_failed, |
|
133 | + .output = ip6_pkt_policy_failed_out, |
133 | + .output = ip6_pkt_policy_failed_out, |
|
134 | + }, |
134 | + }, |
|
135 | + .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP), |
135 | + .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP), |
|
136 | + .rt6i_protocol = RTPROT_KERNEL, |
136 | + .rt6i_protocol = RTPROT_KERNEL, |
|
137 | + .rt6i_metric = ~(u32) 0, |
137 | + .rt6i_metric = ~(u32) 0, |
|
138 | + .rt6i_ref = ATOMIC_INIT(1), |
138 | + .rt6i_ref = ATOMIC_INIT(1), |
|
139 | +}; |
139 | +}; |
|
140 | + |
140 | + |
|
141 | static const struct rt6_info ip6_blk_hole_entry_template = { |
141 | static const struct rt6_info ip6_blk_hole_entry_template = { |
|
142 | .dst = { |
142 | .dst = { |
|
143 | .__refcnt = ATOMIC_INIT(1), |
143 | .__refcnt = ATOMIC_INIT(1), |
|
144 | @@ -2046,6 +2063,11 @@ static struct rt6_info *ip6_route_info_c |
144 | @@ -2043,6 +2060,11 @@ static struct rt6_info *ip6_route_info_c |
|
145 | rt->dst.output = ip6_pkt_prohibit_out; |
145 | rt->dst.output = ip6_pkt_prohibit_out; |
|
146 | rt->dst.input = ip6_pkt_prohibit; |
146 | rt->dst.input = ip6_pkt_prohibit; |
|
147 | break; |
147 | break; |
|
148 | + case RTN_POLICY_FAILED: |
148 | + case RTN_POLICY_FAILED: |
|
149 | + rt->dst.error = -EACCES; |
149 | + rt->dst.error = -EACCES; |
|
150 | + rt->dst.output = ip6_pkt_policy_failed_out; |
150 | + rt->dst.output = ip6_pkt_policy_failed_out; |
|
151 | + rt->dst.input = ip6_pkt_policy_failed; |
151 | + rt->dst.input = ip6_pkt_policy_failed; |
|
152 | + break; |
152 | + break; |
|
153 | case RTN_THROW: |
153 | case RTN_THROW: |
|
154 | case RTN_UNREACHABLE: |
154 | case RTN_UNREACHABLE: |
|
155 | default: |
155 | default: |
|
156 | @@ -2771,6 +2793,17 @@ static int ip6_pkt_prohibit_out(struct n |
156 | @@ -2768,6 +2790,17 @@ static int ip6_pkt_prohibit_out(struct n |
|
157 | return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES); |
157 | return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES); |
|
158 | } |
158 | } |
|
159 | |
159 | |
|
160 | +static int ip6_pkt_policy_failed(struct sk_buff *skb) |
160 | +static int ip6_pkt_policy_failed(struct sk_buff *skb) |
|
161 | +{ |
161 | +{ |
|
162 | + return ip6_pkt_drop(skb, ICMPV6_POLICY_FAIL, IPSTATS_MIB_INNOROUTES); |
162 | + return ip6_pkt_drop(skb, ICMPV6_POLICY_FAIL, IPSTATS_MIB_INNOROUTES); |
|
163 | +} |
163 | +} |
|
164 | + |
164 | + |
|
165 | +static int ip6_pkt_policy_failed_out(struct net *net, struct sock *sk, struct sk_buff *skb) |
165 | +static int ip6_pkt_policy_failed_out(struct net *net, struct sock *sk, struct sk_buff *skb) |
|
166 | +{ |
166 | +{ |
|
167 | + skb->dev = skb_dst(skb)->dev; |
167 | + skb->dev = skb_dst(skb)->dev; |
|
168 | + return ip6_pkt_drop(skb, ICMPV6_POLICY_FAIL, IPSTATS_MIB_OUTNOROUTES); |
168 | + return ip6_pkt_drop(skb, ICMPV6_POLICY_FAIL, IPSTATS_MIB_OUTNOROUTES); |
|
169 | +} |
169 | +} |
|
170 | + |
170 | + |
|
171 | /* |
171 | /* |
|
172 | * Allocate a dst for local (unicast / anycast) address. |
172 | * Allocate a dst for local (unicast / anycast) address. |
|
173 | */ |
173 | */ |
|
174 | @@ -3007,7 +3040,8 @@ static int rtm_to_fib6_config(struct sk_ |
174 | @@ -3004,7 +3037,8 @@ static int rtm_to_fib6_config(struct sk_ |
|
175 | if (rtm->rtm_type == RTN_UNREACHABLE || |
175 | if (rtm->rtm_type == RTN_UNREACHABLE || |
|
176 | rtm->rtm_type == RTN_BLACKHOLE || |
176 | rtm->rtm_type == RTN_BLACKHOLE || |
|
177 | rtm->rtm_type == RTN_PROHIBIT || |
177 | rtm->rtm_type == RTN_PROHIBIT || |
|
178 | - rtm->rtm_type == RTN_THROW) |
178 | - rtm->rtm_type == RTN_THROW) |
|
179 | + rtm->rtm_type == RTN_THROW || |
179 | + rtm->rtm_type == RTN_THROW || |
|
180 | + rtm->rtm_type == RTN_POLICY_FAILED) |
180 | + rtm->rtm_type == RTN_POLICY_FAILED) |
|
181 | cfg->fc_flags |= RTF_REJECT; |
181 | cfg->fc_flags |= RTF_REJECT; |
|
182 | |
182 | |
|
183 | if (rtm->rtm_type == RTN_LOCAL) |
183 | if (rtm->rtm_type == RTN_LOCAL) |
|
184 | @@ -3502,6 +3536,9 @@ static int rt6_fill_node(struct net *net |
184 | @@ -3494,6 +3528,9 @@ static int rt6_fill_node(struct net *net |
|
185 | case -EACCES: |
185 | case -EACCES: |
|
186 | rtm->rtm_type = RTN_PROHIBIT; |
186 | rtm->rtm_type = RTN_PROHIBIT; |
|
187 | break; |
187 | break; |
|
188 | + case -EPERM: |
188 | + case -EPERM: |
|
189 | + rtm->rtm_type = RTN_POLICY_FAILED; |
189 | + rtm->rtm_type = RTN_POLICY_FAILED; |
|
190 | + break; |
190 | + break; |
|
191 | case -EAGAIN: |
191 | case -EAGAIN: |
|
192 | rtm->rtm_type = RTN_THROW; |
192 | rtm->rtm_type = RTN_THROW; |
|
193 | break; |
193 | break; |
|
194 | @@ -3820,6 +3857,8 @@ static int ip6_route_dev_notify(struct n |
194 | @@ -3812,6 +3849,8 @@ static int ip6_route_dev_notify(struct n |
|
195 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES |
195 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES |
|
196 | net->ipv6.ip6_prohibit_entry->dst.dev = dev; |
196 | net->ipv6.ip6_prohibit_entry->dst.dev = dev; |
|
197 | net->ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(dev); |
197 | net->ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(dev); |
|
198 | + net->ipv6.ip6_policy_failed_entry->dst.dev = dev; |
198 | + net->ipv6.ip6_policy_failed_entry->dst.dev = dev; |
|
199 | + net->ipv6.ip6_policy_failed_entry->rt6i_idev = in6_dev_get(dev); |
199 | + net->ipv6.ip6_policy_failed_entry->rt6i_idev = in6_dev_get(dev); |
|
200 | net->ipv6.ip6_blk_hole_entry->dst.dev = dev; |
200 | net->ipv6.ip6_blk_hole_entry->dst.dev = dev; |
|
201 | net->ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(dev); |
201 | net->ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(dev); |
|
202 | #endif |
202 | #endif |
|
203 | @@ -3831,6 +3870,7 @@ static int ip6_route_dev_notify(struct n |
203 | @@ -3823,6 +3862,7 @@ static int ip6_route_dev_notify(struct n |
|
204 | in6_dev_put_clear(&net->ipv6.ip6_null_entry->rt6i_idev); |
204 | in6_dev_put_clear(&net->ipv6.ip6_null_entry->rt6i_idev); |
|
205 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES |
205 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES |
|
206 | in6_dev_put_clear(&net->ipv6.ip6_prohibit_entry->rt6i_idev); |
206 | in6_dev_put_clear(&net->ipv6.ip6_prohibit_entry->rt6i_idev); |
|
207 | + in6_dev_put_clear(&net->ipv6.ip6_policy_failed_entry->rt6i_idev); |
207 | + in6_dev_put_clear(&net->ipv6.ip6_policy_failed_entry->rt6i_idev); |
|
208 | in6_dev_put_clear(&net->ipv6.ip6_blk_hole_entry->rt6i_idev); |
208 | in6_dev_put_clear(&net->ipv6.ip6_blk_hole_entry->rt6i_idev); |
|
209 | #endif |
209 | #endif |
|
210 | } |
210 | } |
|
211 | @@ -4047,6 +4087,17 @@ static int __net_init ip6_route_net_init |
211 | @@ -4039,6 +4079,17 @@ static int __net_init ip6_route_net_init |
|
212 | net->ipv6.ip6_blk_hole_entry->dst.ops = &net->ipv6.ip6_dst_ops; |
212 | net->ipv6.ip6_blk_hole_entry->dst.ops = &net->ipv6.ip6_dst_ops; |
|
213 | dst_init_metrics(&net->ipv6.ip6_blk_hole_entry->dst, |
213 | dst_init_metrics(&net->ipv6.ip6_blk_hole_entry->dst, |
|
214 | ip6_template_metrics, true); |
214 | ip6_template_metrics, true); |
|
215 | + |
215 | + |
|
216 | + net->ipv6.ip6_policy_failed_entry = |
216 | + net->ipv6.ip6_policy_failed_entry = |
|
217 | + kmemdup(&ip6_policy_failed_entry_template, |
217 | + kmemdup(&ip6_policy_failed_entry_template, |
|
218 | + sizeof(*net->ipv6.ip6_policy_failed_entry), GFP_KERNEL); |
218 | + sizeof(*net->ipv6.ip6_policy_failed_entry), GFP_KERNEL); |
|
219 | + if (!net->ipv6.ip6_policy_failed_entry) |
219 | + if (!net->ipv6.ip6_policy_failed_entry) |
|
220 | + goto out_ip6_blk_hole_entry; |
220 | + goto out_ip6_blk_hole_entry; |
|
221 | + net->ipv6.ip6_policy_failed_entry->dst.path = |
221 | + net->ipv6.ip6_policy_failed_entry->dst.path = |
|
222 | + (struct dst_entry *)net->ipv6.ip6_policy_failed_entry; |
222 | + (struct dst_entry *)net->ipv6.ip6_policy_failed_entry; |
|
223 | + net->ipv6.ip6_policy_failed_entry->dst.ops = &net->ipv6.ip6_dst_ops; |
223 | + net->ipv6.ip6_policy_failed_entry->dst.ops = &net->ipv6.ip6_dst_ops; |
|
224 | + dst_init_metrics(&net->ipv6.ip6_policy_failed_entry->dst, |
224 | + dst_init_metrics(&net->ipv6.ip6_policy_failed_entry->dst, |
|
225 | + ip6_template_metrics, true); |
225 | + ip6_template_metrics, true); |
|
226 | #endif |
226 | #endif |
|
227 | |
227 | |
|
228 | net->ipv6.sysctl.flush_delay = 0; |
228 | net->ipv6.sysctl.flush_delay = 0; |
|
229 | @@ -4065,6 +4116,8 @@ out: |
229 | @@ -4057,6 +4108,8 @@ out: |
|
230 | return ret; |
230 | return ret; |
|
231 | |
231 | |
|
232 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES |
232 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES |
|
233 | +out_ip6_blk_hole_entry: |
233 | +out_ip6_blk_hole_entry: |
|
234 | + kfree(net->ipv6.ip6_blk_hole_entry); |
234 | + kfree(net->ipv6.ip6_blk_hole_entry); |
|
235 | out_ip6_prohibit_entry: |
235 | out_ip6_prohibit_entry: |
|
236 | kfree(net->ipv6.ip6_prohibit_entry); |
236 | kfree(net->ipv6.ip6_prohibit_entry); |
|
237 | out_ip6_null_entry: |
237 | out_ip6_null_entry: |
|
238 | @@ -4082,6 +4135,7 @@ static void __net_exit ip6_route_net_exi |
238 | @@ -4074,6 +4127,7 @@ static void __net_exit ip6_route_net_exi |
|
239 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES |
239 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES |
|
240 | kfree(net->ipv6.ip6_prohibit_entry); |
240 | kfree(net->ipv6.ip6_prohibit_entry); |
|
241 | kfree(net->ipv6.ip6_blk_hole_entry); |
241 | kfree(net->ipv6.ip6_blk_hole_entry); |
|
242 | + kfree(net->ipv6.ip6_policy_failed_entry); |
242 | + kfree(net->ipv6.ip6_policy_failed_entry); |
|
243 | #endif |
243 | #endif |
|
244 | dst_entries_destroy(&net->ipv6.ip6_dst_ops); |
244 | dst_entries_destroy(&net->ipv6.ip6_dst_ops); |
|
245 | } |
245 | } |
|
246 | @@ -4155,6 +4209,9 @@ void __init ip6_route_init_special_entri |
246 | @@ -4147,6 +4201,9 @@ void __init ip6_route_init_special_entri |
|
247 | init_net.ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); |
247 | init_net.ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); |
|
248 | init_net.ipv6.ip6_blk_hole_entry->dst.dev = init_net.loopback_dev; |
248 | init_net.ipv6.ip6_blk_hole_entry->dst.dev = init_net.loopback_dev; |
|
249 | init_net.ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); |
249 | init_net.ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); |
|
250 | + init_net.ipv6.ip6_policy_failed_entry->dst.dev = init_net.loopback_dev; |
250 | + init_net.ipv6.ip6_policy_failed_entry->dst.dev = init_net.loopback_dev; |
|
251 | + init_net.ipv6.ip6_policy_failed_entry->rt6i_idev = |
251 | + init_net.ipv6.ip6_policy_failed_entry->rt6i_idev = |
|
252 | + in6_dev_get(init_net.loopback_dev); |
252 | + in6_dev_get(init_net.loopback_dev); |
|
253 | #endif |
253 | #endif |
|
254 | } |
254 | } |
|
255 | |
255 | |
|
256 | |
256 | |