diff options
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/Kconfig | 4 | ||||
-rw-r--r-- | net/ipv4/af_inet.c | 2 | ||||
-rw-r--r-- | net/ipv4/fib_rules.c | 10 | ||||
-rw-r--r-- | net/ipv4/fib_semantics.c | 22 | ||||
-rw-r--r-- | net/ipv4/inetpeer.c | 1 | ||||
-rw-r--r-- | net/ipv4/ip_input.c | 2 | ||||
-rw-r--r-- | net/ipv4/netfilter/Kconfig | 3 | ||||
-rw-r--r-- | net/ipv4/netfilter/arp_tables.c | 2 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_tables.c | 2 | ||||
-rw-r--r-- | net/ipv4/netfilter/ipt_CLUSTERIP.c | 7 | ||||
-rw-r--r-- | net/ipv4/netfilter/ipt_LOG.c | 3 | ||||
-rw-r--r-- | net/ipv4/netfilter/iptable_mangle.c | 2 | ||||
-rw-r--r-- | net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c | 17 | ||||
-rw-r--r-- | net/ipv4/netfilter/nf_nat_amanda.c | 8 | ||||
-rw-r--r-- | net/ipv4/netfilter/nf_nat_core.c | 33 | ||||
-rw-r--r-- | net/ipv4/netfilter/nf_nat_snmp_basic.c | 9 | ||||
-rw-r--r-- | net/ipv4/route.c | 97 | ||||
-rw-r--r-- | net/ipv4/tcp.c | 2 | ||||
-rw-r--r-- | net/ipv4/udp.c | 2 | ||||
-rw-r--r-- | net/ipv4/xfrm4_policy.c | 4 |
20 files changed, 163 insertions, 69 deletions
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig index a5a1050595d1..8949a05ac307 100644 --- a/net/ipv4/Kconfig +++ b/net/ipv4/Kconfig | |||
@@ -140,6 +140,9 @@ config IP_ROUTE_VERBOSE | |||
140 | handled by the klogd daemon which is responsible for kernel messages | 140 | handled by the klogd daemon which is responsible for kernel messages |
141 | ("man klogd"). | 141 | ("man klogd"). |
142 | 142 | ||
143 | config IP_ROUTE_CLASSID | ||
144 | bool | ||
145 | |||
143 | config IP_PNP | 146 | config IP_PNP |
144 | bool "IP: kernel level autoconfiguration" | 147 | bool "IP: kernel level autoconfiguration" |
145 | help | 148 | help |
@@ -657,4 +660,3 @@ config TCP_MD5SIG | |||
657 | on the Internet. | 660 | on the Internet. |
658 | 661 | ||
659 | If unsure, say N. | 662 | If unsure, say N. |
660 | |||
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 45b89d7bda5a..7ceb80447631 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
@@ -1231,7 +1231,7 @@ out: | |||
1231 | return err; | 1231 | return err; |
1232 | } | 1232 | } |
1233 | 1233 | ||
1234 | static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int features) | 1234 | static struct sk_buff *inet_gso_segment(struct sk_buff *skb, u32 features) |
1235 | { | 1235 | { |
1236 | struct sk_buff *segs = ERR_PTR(-EINVAL); | 1236 | struct sk_buff *segs = ERR_PTR(-EINVAL); |
1237 | struct iphdr *iph; | 1237 | struct iphdr *iph; |
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c index 7981a24f5c7b..9cefe72029cf 100644 --- a/net/ipv4/fib_rules.c +++ b/net/ipv4/fib_rules.c | |||
@@ -41,12 +41,12 @@ struct fib4_rule { | |||
41 | __be32 srcmask; | 41 | __be32 srcmask; |
42 | __be32 dst; | 42 | __be32 dst; |
43 | __be32 dstmask; | 43 | __be32 dstmask; |
44 | #ifdef CONFIG_NET_CLS_ROUTE | 44 | #ifdef CONFIG_IP_ROUTE_CLASSID |
45 | u32 tclassid; | 45 | u32 tclassid; |
46 | #endif | 46 | #endif |
47 | }; | 47 | }; |
48 | 48 | ||
49 | #ifdef CONFIG_NET_CLS_ROUTE | 49 | #ifdef CONFIG_IP_ROUTE_CLASSID |
50 | u32 fib_rules_tclass(struct fib_result *res) | 50 | u32 fib_rules_tclass(struct fib_result *res) |
51 | { | 51 | { |
52 | return res->r ? ((struct fib4_rule *) res->r)->tclassid : 0; | 52 | return res->r ? ((struct fib4_rule *) res->r)->tclassid : 0; |
@@ -165,7 +165,7 @@ static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb, | |||
165 | if (frh->dst_len) | 165 | if (frh->dst_len) |
166 | rule4->dst = nla_get_be32(tb[FRA_DST]); | 166 | rule4->dst = nla_get_be32(tb[FRA_DST]); |
167 | 167 | ||
168 | #ifdef CONFIG_NET_CLS_ROUTE | 168 | #ifdef CONFIG_IP_ROUTE_CLASSID |
169 | if (tb[FRA_FLOW]) | 169 | if (tb[FRA_FLOW]) |
170 | rule4->tclassid = nla_get_u32(tb[FRA_FLOW]); | 170 | rule4->tclassid = nla_get_u32(tb[FRA_FLOW]); |
171 | #endif | 171 | #endif |
@@ -195,7 +195,7 @@ static int fib4_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh, | |||
195 | if (frh->tos && (rule4->tos != frh->tos)) | 195 | if (frh->tos && (rule4->tos != frh->tos)) |
196 | return 0; | 196 | return 0; |
197 | 197 | ||
198 | #ifdef CONFIG_NET_CLS_ROUTE | 198 | #ifdef CONFIG_IP_ROUTE_CLASSID |
199 | if (tb[FRA_FLOW] && (rule4->tclassid != nla_get_u32(tb[FRA_FLOW]))) | 199 | if (tb[FRA_FLOW] && (rule4->tclassid != nla_get_u32(tb[FRA_FLOW]))) |
200 | return 0; | 200 | return 0; |
201 | #endif | 201 | #endif |
@@ -224,7 +224,7 @@ static int fib4_rule_fill(struct fib_rule *rule, struct sk_buff *skb, | |||
224 | if (rule4->src_len) | 224 | if (rule4->src_len) |
225 | NLA_PUT_BE32(skb, FRA_SRC, rule4->src); | 225 | NLA_PUT_BE32(skb, FRA_SRC, rule4->src); |
226 | 226 | ||
227 | #ifdef CONFIG_NET_CLS_ROUTE | 227 | #ifdef CONFIG_IP_ROUTE_CLASSID |
228 | if (rule4->tclassid) | 228 | if (rule4->tclassid) |
229 | NLA_PUT_U32(skb, FRA_FLOW, rule4->tclassid); | 229 | NLA_PUT_U32(skb, FRA_FLOW, rule4->tclassid); |
230 | #endif | 230 | #endif |
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index 12d3dc3df1b7..48e93a560077 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c | |||
@@ -152,6 +152,8 @@ static void free_fib_info_rcu(struct rcu_head *head) | |||
152 | { | 152 | { |
153 | struct fib_info *fi = container_of(head, struct fib_info, rcu); | 153 | struct fib_info *fi = container_of(head, struct fib_info, rcu); |
154 | 154 | ||
155 | if (fi->fib_metrics != (u32 *) dst_default_metrics) | ||
156 | kfree(fi->fib_metrics); | ||
155 | kfree(fi); | 157 | kfree(fi); |
156 | } | 158 | } |
157 | 159 | ||
@@ -200,7 +202,7 @@ static inline int nh_comp(const struct fib_info *fi, const struct fib_info *ofi) | |||
200 | #ifdef CONFIG_IP_ROUTE_MULTIPATH | 202 | #ifdef CONFIG_IP_ROUTE_MULTIPATH |
201 | nh->nh_weight != onh->nh_weight || | 203 | nh->nh_weight != onh->nh_weight || |
202 | #endif | 204 | #endif |
203 | #ifdef CONFIG_NET_CLS_ROUTE | 205 | #ifdef CONFIG_IP_ROUTE_CLASSID |
204 | nh->nh_tclassid != onh->nh_tclassid || | 206 | nh->nh_tclassid != onh->nh_tclassid || |
205 | #endif | 207 | #endif |
206 | ((nh->nh_flags ^ onh->nh_flags) & ~RTNH_F_DEAD)) | 208 | ((nh->nh_flags ^ onh->nh_flags) & ~RTNH_F_DEAD)) |
@@ -422,7 +424,7 @@ static int fib_get_nhs(struct fib_info *fi, struct rtnexthop *rtnh, | |||
422 | 424 | ||
423 | nla = nla_find(attrs, attrlen, RTA_GATEWAY); | 425 | nla = nla_find(attrs, attrlen, RTA_GATEWAY); |
424 | nexthop_nh->nh_gw = nla ? nla_get_be32(nla) : 0; | 426 | nexthop_nh->nh_gw = nla ? nla_get_be32(nla) : 0; |
425 | #ifdef CONFIG_NET_CLS_ROUTE | 427 | #ifdef CONFIG_IP_ROUTE_CLASSID |
426 | nla = nla_find(attrs, attrlen, RTA_FLOW); | 428 | nla = nla_find(attrs, attrlen, RTA_FLOW); |
427 | nexthop_nh->nh_tclassid = nla ? nla_get_u32(nla) : 0; | 429 | nexthop_nh->nh_tclassid = nla ? nla_get_u32(nla) : 0; |
428 | #endif | 430 | #endif |
@@ -476,7 +478,7 @@ int fib_nh_match(struct fib_config *cfg, struct fib_info *fi) | |||
476 | nla = nla_find(attrs, attrlen, RTA_GATEWAY); | 478 | nla = nla_find(attrs, attrlen, RTA_GATEWAY); |
477 | if (nla && nla_get_be32(nla) != nh->nh_gw) | 479 | if (nla && nla_get_be32(nla) != nh->nh_gw) |
478 | return 1; | 480 | return 1; |
479 | #ifdef CONFIG_NET_CLS_ROUTE | 481 | #ifdef CONFIG_IP_ROUTE_CLASSID |
480 | nla = nla_find(attrs, attrlen, RTA_FLOW); | 482 | nla = nla_find(attrs, attrlen, RTA_FLOW); |
481 | if (nla && nla_get_u32(nla) != nh->nh_tclassid) | 483 | if (nla && nla_get_u32(nla) != nh->nh_tclassid) |
482 | return 1; | 484 | return 1; |
@@ -742,6 +744,12 @@ struct fib_info *fib_create_info(struct fib_config *cfg) | |||
742 | fi = kzalloc(sizeof(*fi)+nhs*sizeof(struct fib_nh), GFP_KERNEL); | 744 | fi = kzalloc(sizeof(*fi)+nhs*sizeof(struct fib_nh), GFP_KERNEL); |
743 | if (fi == NULL) | 745 | if (fi == NULL) |
744 | goto failure; | 746 | goto failure; |
747 | if (cfg->fc_mx) { | ||
748 | fi->fib_metrics = kzalloc(sizeof(u32) * RTAX_MAX, GFP_KERNEL); | ||
749 | if (!fi->fib_metrics) | ||
750 | goto failure; | ||
751 | } else | ||
752 | fi->fib_metrics = (u32 *) dst_default_metrics; | ||
745 | fib_info_cnt++; | 753 | fib_info_cnt++; |
746 | 754 | ||
747 | fi->fib_net = hold_net(net); | 755 | fi->fib_net = hold_net(net); |
@@ -779,7 +787,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg) | |||
779 | goto err_inval; | 787 | goto err_inval; |
780 | if (cfg->fc_gw && fi->fib_nh->nh_gw != cfg->fc_gw) | 788 | if (cfg->fc_gw && fi->fib_nh->nh_gw != cfg->fc_gw) |
781 | goto err_inval; | 789 | goto err_inval; |
782 | #ifdef CONFIG_NET_CLS_ROUTE | 790 | #ifdef CONFIG_IP_ROUTE_CLASSID |
783 | if (cfg->fc_flow && fi->fib_nh->nh_tclassid != cfg->fc_flow) | 791 | if (cfg->fc_flow && fi->fib_nh->nh_tclassid != cfg->fc_flow) |
784 | goto err_inval; | 792 | goto err_inval; |
785 | #endif | 793 | #endif |
@@ -792,7 +800,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg) | |||
792 | nh->nh_oif = cfg->fc_oif; | 800 | nh->nh_oif = cfg->fc_oif; |
793 | nh->nh_gw = cfg->fc_gw; | 801 | nh->nh_gw = cfg->fc_gw; |
794 | nh->nh_flags = cfg->fc_flags; | 802 | nh->nh_flags = cfg->fc_flags; |
795 | #ifdef CONFIG_NET_CLS_ROUTE | 803 | #ifdef CONFIG_IP_ROUTE_CLASSID |
796 | nh->nh_tclassid = cfg->fc_flow; | 804 | nh->nh_tclassid = cfg->fc_flow; |
797 | #endif | 805 | #endif |
798 | #ifdef CONFIG_IP_ROUTE_MULTIPATH | 806 | #ifdef CONFIG_IP_ROUTE_MULTIPATH |
@@ -1002,7 +1010,7 @@ int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, | |||
1002 | 1010 | ||
1003 | if (fi->fib_nh->nh_oif) | 1011 | if (fi->fib_nh->nh_oif) |
1004 | NLA_PUT_U32(skb, RTA_OIF, fi->fib_nh->nh_oif); | 1012 | NLA_PUT_U32(skb, RTA_OIF, fi->fib_nh->nh_oif); |
1005 | #ifdef CONFIG_NET_CLS_ROUTE | 1013 | #ifdef CONFIG_IP_ROUTE_CLASSID |
1006 | if (fi->fib_nh[0].nh_tclassid) | 1014 | if (fi->fib_nh[0].nh_tclassid) |
1007 | NLA_PUT_U32(skb, RTA_FLOW, fi->fib_nh[0].nh_tclassid); | 1015 | NLA_PUT_U32(skb, RTA_FLOW, fi->fib_nh[0].nh_tclassid); |
1008 | #endif | 1016 | #endif |
@@ -1027,7 +1035,7 @@ int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, | |||
1027 | 1035 | ||
1028 | if (nh->nh_gw) | 1036 | if (nh->nh_gw) |
1029 | NLA_PUT_BE32(skb, RTA_GATEWAY, nh->nh_gw); | 1037 | NLA_PUT_BE32(skb, RTA_GATEWAY, nh->nh_gw); |
1030 | #ifdef CONFIG_NET_CLS_ROUTE | 1038 | #ifdef CONFIG_IP_ROUTE_CLASSID |
1031 | if (nh->nh_tclassid) | 1039 | if (nh->nh_tclassid) |
1032 | NLA_PUT_U32(skb, RTA_FLOW, nh->nh_tclassid); | 1040 | NLA_PUT_U32(skb, RTA_FLOW, nh->nh_tclassid); |
1033 | #endif | 1041 | #endif |
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c index a96e65674ac3..b6513b13d729 100644 --- a/net/ipv4/inetpeer.c +++ b/net/ipv4/inetpeer.c | |||
@@ -512,6 +512,7 @@ struct inet_peer *inet_getpeer(struct inetpeer_addr *daddr, int create) | |||
512 | atomic_set(&p->rid, 0); | 512 | atomic_set(&p->rid, 0); |
513 | atomic_set(&p->ip_id_count, secure_ip_id(daddr->a4)); | 513 | atomic_set(&p->ip_id_count, secure_ip_id(daddr->a4)); |
514 | p->tcp_ts_stamp = 0; | 514 | p->tcp_ts_stamp = 0; |
515 | p->metrics[RTAX_LOCK-1] = INETPEER_METRICS_NEW; | ||
515 | INIT_LIST_HEAD(&p->unused); | 516 | INIT_LIST_HEAD(&p->unused); |
516 | 517 | ||
517 | 518 | ||
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index d859bcc26cb7..d7b2b0987a3b 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c | |||
@@ -340,7 +340,7 @@ static int ip_rcv_finish(struct sk_buff *skb) | |||
340 | } | 340 | } |
341 | } | 341 | } |
342 | 342 | ||
343 | #ifdef CONFIG_NET_CLS_ROUTE | 343 | #ifdef CONFIG_IP_ROUTE_CLASSID |
344 | if (unlikely(skb_dst(skb)->tclassid)) { | 344 | if (unlikely(skb_dst(skb)->tclassid)) { |
345 | struct ip_rt_acct *st = this_cpu_ptr(ip_rt_acct); | 345 | struct ip_rt_acct *st = this_cpu_ptr(ip_rt_acct); |
346 | u32 idx = skb_dst(skb)->tclassid; | 346 | u32 idx = skb_dst(skb)->tclassid; |
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig index babd1a2bae5f..f926a310075d 100644 --- a/net/ipv4/netfilter/Kconfig +++ b/net/ipv4/netfilter/Kconfig | |||
@@ -206,8 +206,9 @@ config IP_NF_TARGET_REDIRECT | |||
206 | 206 | ||
207 | config NF_NAT_SNMP_BASIC | 207 | config NF_NAT_SNMP_BASIC |
208 | tristate "Basic SNMP-ALG support" | 208 | tristate "Basic SNMP-ALG support" |
209 | depends on NF_NAT | 209 | depends on NF_CONNTRACK_SNMP && NF_NAT |
210 | depends on NETFILTER_ADVANCED | 210 | depends on NETFILTER_ADVANCED |
211 | default NF_NAT && NF_CONNTRACK_SNMP | ||
211 | ---help--- | 212 | ---help--- |
212 | 213 | ||
213 | This module implements an Application Layer Gateway (ALG) for | 214 | This module implements an Application Layer Gateway (ALG) for |
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index e855fffaed95..e95054c690c6 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c | |||
@@ -866,6 +866,7 @@ static int compat_table_info(const struct xt_table_info *info, | |||
866 | memcpy(newinfo, info, offsetof(struct xt_table_info, entries)); | 866 | memcpy(newinfo, info, offsetof(struct xt_table_info, entries)); |
867 | newinfo->initial_entries = 0; | 867 | newinfo->initial_entries = 0; |
868 | loc_cpu_entry = info->entries[raw_smp_processor_id()]; | 868 | loc_cpu_entry = info->entries[raw_smp_processor_id()]; |
869 | xt_compat_init_offsets(NFPROTO_ARP, info->number); | ||
869 | xt_entry_foreach(iter, loc_cpu_entry, info->size) { | 870 | xt_entry_foreach(iter, loc_cpu_entry, info->size) { |
870 | ret = compat_calc_entry(iter, info, loc_cpu_entry, newinfo); | 871 | ret = compat_calc_entry(iter, info, loc_cpu_entry, newinfo); |
871 | if (ret != 0) | 872 | if (ret != 0) |
@@ -1333,6 +1334,7 @@ static int translate_compat_table(const char *name, | |||
1333 | duprintf("translate_compat_table: size %u\n", info->size); | 1334 | duprintf("translate_compat_table: size %u\n", info->size); |
1334 | j = 0; | 1335 | j = 0; |
1335 | xt_compat_lock(NFPROTO_ARP); | 1336 | xt_compat_lock(NFPROTO_ARP); |
1337 | xt_compat_init_offsets(NFPROTO_ARP, number); | ||
1336 | /* Walk through entries, checking offsets. */ | 1338 | /* Walk through entries, checking offsets. */ |
1337 | xt_entry_foreach(iter0, entry0, total_size) { | 1339 | xt_entry_foreach(iter0, entry0, total_size) { |
1338 | ret = check_compat_entry_size_and_hooks(iter0, info, &size, | 1340 | ret = check_compat_entry_size_and_hooks(iter0, info, &size, |
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 652efea013dc..ef7d7b9680ea 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
@@ -1063,6 +1063,7 @@ static int compat_table_info(const struct xt_table_info *info, | |||
1063 | memcpy(newinfo, info, offsetof(struct xt_table_info, entries)); | 1063 | memcpy(newinfo, info, offsetof(struct xt_table_info, entries)); |
1064 | newinfo->initial_entries = 0; | 1064 | newinfo->initial_entries = 0; |
1065 | loc_cpu_entry = info->entries[raw_smp_processor_id()]; | 1065 | loc_cpu_entry = info->entries[raw_smp_processor_id()]; |
1066 | xt_compat_init_offsets(AF_INET, info->number); | ||
1066 | xt_entry_foreach(iter, loc_cpu_entry, info->size) { | 1067 | xt_entry_foreach(iter, loc_cpu_entry, info->size) { |
1067 | ret = compat_calc_entry(iter, info, loc_cpu_entry, newinfo); | 1068 | ret = compat_calc_entry(iter, info, loc_cpu_entry, newinfo); |
1068 | if (ret != 0) | 1069 | if (ret != 0) |
@@ -1664,6 +1665,7 @@ translate_compat_table(struct net *net, | |||
1664 | duprintf("translate_compat_table: size %u\n", info->size); | 1665 | duprintf("translate_compat_table: size %u\n", info->size); |
1665 | j = 0; | 1666 | j = 0; |
1666 | xt_compat_lock(AF_INET); | 1667 | xt_compat_lock(AF_INET); |
1668 | xt_compat_init_offsets(AF_INET, number); | ||
1667 | /* Walk through entries, checking offsets. */ | 1669 | /* Walk through entries, checking offsets. */ |
1668 | xt_entry_foreach(iter0, entry0, total_size) { | 1670 | xt_entry_foreach(iter0, entry0, total_size) { |
1669 | ret = check_compat_entry_size_and_hooks(iter0, info, &size, | 1671 | ret = check_compat_entry_size_and_hooks(iter0, info, &size, |
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c index 1e26a4897655..403ca57f6011 100644 --- a/net/ipv4/netfilter/ipt_CLUSTERIP.c +++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c | |||
@@ -300,13 +300,8 @@ clusterip_tg(struct sk_buff *skb, const struct xt_action_param *par) | |||
300 | * that the ->target() function isn't called after ->destroy() */ | 300 | * that the ->target() function isn't called after ->destroy() */ |
301 | 301 | ||
302 | ct = nf_ct_get(skb, &ctinfo); | 302 | ct = nf_ct_get(skb, &ctinfo); |
303 | if (ct == NULL) { | 303 | if (ct == NULL) |
304 | pr_info("no conntrack!\n"); | ||
305 | /* FIXME: need to drop invalid ones, since replies | ||
306 | * to outgoing connections of other nodes will be | ||
307 | * marked as INVALID */ | ||
308 | return NF_DROP; | 304 | return NF_DROP; |
309 | } | ||
310 | 305 | ||
311 | /* special case: ICMP error handling. conntrack distinguishes between | 306 | /* special case: ICMP error handling. conntrack distinguishes between |
312 | * error messages (RELATED) and information requests (see below) */ | 307 | * error messages (RELATED) and information requests (see below) */ |
diff --git a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c index 72ffc8fda2e9..d76d6c9ed946 100644 --- a/net/ipv4/netfilter/ipt_LOG.c +++ b/net/ipv4/netfilter/ipt_LOG.c | |||
@@ -442,8 +442,7 @@ ipt_log_packet(u_int8_t pf, | |||
442 | } | 442 | } |
443 | #endif | 443 | #endif |
444 | 444 | ||
445 | /* MAC logging for input path only. */ | 445 | if (in != NULL) |
446 | if (in && !out) | ||
447 | dump_mac_header(m, loginfo, skb); | 446 | dump_mac_header(m, loginfo, skb); |
448 | 447 | ||
449 | dump_packet(m, loginfo, skb, 0); | 448 | dump_packet(m, loginfo, skb, 0); |
diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c index 294a2a32f293..aef5d1fbe77d 100644 --- a/net/ipv4/netfilter/iptable_mangle.c +++ b/net/ipv4/netfilter/iptable_mangle.c | |||
@@ -60,7 +60,7 @@ ipt_mangle_out(struct sk_buff *skb, const struct net_device *out) | |||
60 | ret = ipt_do_table(skb, NF_INET_LOCAL_OUT, NULL, out, | 60 | ret = ipt_do_table(skb, NF_INET_LOCAL_OUT, NULL, out, |
61 | dev_net(out)->ipv4.iptable_mangle); | 61 | dev_net(out)->ipv4.iptable_mangle); |
62 | /* Reroute for ANY change. */ | 62 | /* Reroute for ANY change. */ |
63 | if (ret != NF_DROP && ret != NF_STOLEN && ret != NF_QUEUE) { | 63 | if (ret != NF_DROP && ret != NF_STOLEN) { |
64 | iph = ip_hdr(skb); | 64 | iph = ip_hdr(skb); |
65 | 65 | ||
66 | if (iph->saddr != saddr || | 66 | if (iph->saddr != saddr || |
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c index 63f60fc5d26a..5585980fce2e 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <net/netfilter/nf_conntrack_l4proto.h> | 20 | #include <net/netfilter/nf_conntrack_l4proto.h> |
21 | #include <net/netfilter/nf_conntrack_expect.h> | 21 | #include <net/netfilter/nf_conntrack_expect.h> |
22 | #include <net/netfilter/nf_conntrack_acct.h> | 22 | #include <net/netfilter/nf_conntrack_acct.h> |
23 | #include <linux/rculist_nulls.h> | ||
23 | 24 | ||
24 | struct ct_iter_state { | 25 | struct ct_iter_state { |
25 | struct seq_net_private p; | 26 | struct seq_net_private p; |
@@ -35,7 +36,8 @@ static struct hlist_nulls_node *ct_get_first(struct seq_file *seq) | |||
35 | for (st->bucket = 0; | 36 | for (st->bucket = 0; |
36 | st->bucket < net->ct.htable_size; | 37 | st->bucket < net->ct.htable_size; |
37 | st->bucket++) { | 38 | st->bucket++) { |
38 | n = rcu_dereference(net->ct.hash[st->bucket].first); | 39 | n = rcu_dereference( |
40 | hlist_nulls_first_rcu(&net->ct.hash[st->bucket])); | ||
39 | if (!is_a_nulls(n)) | 41 | if (!is_a_nulls(n)) |
40 | return n; | 42 | return n; |
41 | } | 43 | } |
@@ -48,13 +50,14 @@ static struct hlist_nulls_node *ct_get_next(struct seq_file *seq, | |||
48 | struct net *net = seq_file_net(seq); | 50 | struct net *net = seq_file_net(seq); |
49 | struct ct_iter_state *st = seq->private; | 51 | struct ct_iter_state *st = seq->private; |
50 | 52 | ||
51 | head = rcu_dereference(head->next); | 53 | head = rcu_dereference(hlist_nulls_next_rcu(head)); |
52 | while (is_a_nulls(head)) { | 54 | while (is_a_nulls(head)) { |
53 | if (likely(get_nulls_value(head) == st->bucket)) { | 55 | if (likely(get_nulls_value(head) == st->bucket)) { |
54 | if (++st->bucket >= net->ct.htable_size) | 56 | if (++st->bucket >= net->ct.htable_size) |
55 | return NULL; | 57 | return NULL; |
56 | } | 58 | } |
57 | head = rcu_dereference(net->ct.hash[st->bucket].first); | 59 | head = rcu_dereference( |
60 | hlist_nulls_first_rcu(&net->ct.hash[st->bucket])); | ||
58 | } | 61 | } |
59 | return head; | 62 | return head; |
60 | } | 63 | } |
@@ -217,7 +220,8 @@ static struct hlist_node *ct_expect_get_first(struct seq_file *seq) | |||
217 | struct hlist_node *n; | 220 | struct hlist_node *n; |
218 | 221 | ||
219 | for (st->bucket = 0; st->bucket < nf_ct_expect_hsize; st->bucket++) { | 222 | for (st->bucket = 0; st->bucket < nf_ct_expect_hsize; st->bucket++) { |
220 | n = rcu_dereference(net->ct.expect_hash[st->bucket].first); | 223 | n = rcu_dereference( |
224 | hlist_first_rcu(&net->ct.expect_hash[st->bucket])); | ||
221 | if (n) | 225 | if (n) |
222 | return n; | 226 | return n; |
223 | } | 227 | } |
@@ -230,11 +234,12 @@ static struct hlist_node *ct_expect_get_next(struct seq_file *seq, | |||
230 | struct net *net = seq_file_net(seq); | 234 | struct net *net = seq_file_net(seq); |
231 | struct ct_expect_iter_state *st = seq->private; | 235 | struct ct_expect_iter_state *st = seq->private; |
232 | 236 | ||
233 | head = rcu_dereference(head->next); | 237 | head = rcu_dereference(hlist_next_rcu(head)); |
234 | while (head == NULL) { | 238 | while (head == NULL) { |
235 | if (++st->bucket >= nf_ct_expect_hsize) | 239 | if (++st->bucket >= nf_ct_expect_hsize) |
236 | return NULL; | 240 | return NULL; |
237 | head = rcu_dereference(net->ct.expect_hash[st->bucket].first); | 241 | head = rcu_dereference( |
242 | hlist_first_rcu(&net->ct.expect_hash[st->bucket])); | ||
238 | } | 243 | } |
239 | return head; | 244 | return head; |
240 | } | 245 | } |
diff --git a/net/ipv4/netfilter/nf_nat_amanda.c b/net/ipv4/netfilter/nf_nat_amanda.c index 0f23b3f06df0..703f366fd235 100644 --- a/net/ipv4/netfilter/nf_nat_amanda.c +++ b/net/ipv4/netfilter/nf_nat_amanda.c | |||
@@ -44,13 +44,13 @@ static unsigned int help(struct sk_buff *skb, | |||
44 | 44 | ||
45 | /* Try to get same port: if not, try to change it. */ | 45 | /* Try to get same port: if not, try to change it. */ |
46 | for (port = ntohs(exp->saved_proto.tcp.port); port != 0; port++) { | 46 | for (port = ntohs(exp->saved_proto.tcp.port); port != 0; port++) { |
47 | int ret; | 47 | int res; |
48 | 48 | ||
49 | exp->tuple.dst.u.tcp.port = htons(port); | 49 | exp->tuple.dst.u.tcp.port = htons(port); |
50 | ret = nf_ct_expect_related(exp); | 50 | res = nf_ct_expect_related(exp); |
51 | if (ret == 0) | 51 | if (res == 0) |
52 | break; | 52 | break; |
53 | else if (ret != -EBUSY) { | 53 | else if (res != -EBUSY) { |
54 | port = 0; | 54 | port = 0; |
55 | break; | 55 | break; |
56 | } | 56 | } |
diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c index c04787ce1a71..21bcf471b25a 100644 --- a/net/ipv4/netfilter/nf_nat_core.c +++ b/net/ipv4/netfilter/nf_nat_core.c | |||
@@ -221,7 +221,14 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple, | |||
221 | manips not an issue. */ | 221 | manips not an issue. */ |
222 | if (maniptype == IP_NAT_MANIP_SRC && | 222 | if (maniptype == IP_NAT_MANIP_SRC && |
223 | !(range->flags & IP_NAT_RANGE_PROTO_RANDOM)) { | 223 | !(range->flags & IP_NAT_RANGE_PROTO_RANDOM)) { |
224 | if (find_appropriate_src(net, zone, orig_tuple, tuple, range)) { | 224 | /* try the original tuple first */ |
225 | if (in_range(orig_tuple, range)) { | ||
226 | if (!nf_nat_used_tuple(orig_tuple, ct)) { | ||
227 | *tuple = *orig_tuple; | ||
228 | return; | ||
229 | } | ||
230 | } else if (find_appropriate_src(net, zone, orig_tuple, tuple, | ||
231 | range)) { | ||
225 | pr_debug("get_unique_tuple: Found current src map\n"); | 232 | pr_debug("get_unique_tuple: Found current src map\n"); |
226 | if (!nf_nat_used_tuple(tuple, ct)) | 233 | if (!nf_nat_used_tuple(tuple, ct)) |
227 | return; | 234 | return; |
@@ -266,7 +273,6 @@ nf_nat_setup_info(struct nf_conn *ct, | |||
266 | struct net *net = nf_ct_net(ct); | 273 | struct net *net = nf_ct_net(ct); |
267 | struct nf_conntrack_tuple curr_tuple, new_tuple; | 274 | struct nf_conntrack_tuple curr_tuple, new_tuple; |
268 | struct nf_conn_nat *nat; | 275 | struct nf_conn_nat *nat; |
269 | int have_to_hash = !(ct->status & IPS_NAT_DONE_MASK); | ||
270 | 276 | ||
271 | /* nat helper or nfctnetlink also setup binding */ | 277 | /* nat helper or nfctnetlink also setup binding */ |
272 | nat = nfct_nat(ct); | 278 | nat = nfct_nat(ct); |
@@ -306,8 +312,7 @@ nf_nat_setup_info(struct nf_conn *ct, | |||
306 | ct->status |= IPS_DST_NAT; | 312 | ct->status |= IPS_DST_NAT; |
307 | } | 313 | } |
308 | 314 | ||
309 | /* Place in source hash if this is the first time. */ | 315 | if (maniptype == IP_NAT_MANIP_SRC) { |
310 | if (have_to_hash) { | ||
311 | unsigned int srchash; | 316 | unsigned int srchash; |
312 | 317 | ||
313 | srchash = hash_by_src(net, nf_ct_zone(ct), | 318 | srchash = hash_by_src(net, nf_ct_zone(ct), |
@@ -323,9 +328,9 @@ nf_nat_setup_info(struct nf_conn *ct, | |||
323 | 328 | ||
324 | /* It's done. */ | 329 | /* It's done. */ |
325 | if (maniptype == IP_NAT_MANIP_DST) | 330 | if (maniptype == IP_NAT_MANIP_DST) |
326 | set_bit(IPS_DST_NAT_DONE_BIT, &ct->status); | 331 | ct->status |= IPS_DST_NAT_DONE; |
327 | else | 332 | else |
328 | set_bit(IPS_SRC_NAT_DONE_BIT, &ct->status); | 333 | ct->status |= IPS_SRC_NAT_DONE; |
329 | 334 | ||
330 | return NF_ACCEPT; | 335 | return NF_ACCEPT; |
331 | } | 336 | } |
@@ -502,7 +507,10 @@ int nf_nat_protocol_register(const struct nf_nat_protocol *proto) | |||
502 | int ret = 0; | 507 | int ret = 0; |
503 | 508 | ||
504 | spin_lock_bh(&nf_nat_lock); | 509 | spin_lock_bh(&nf_nat_lock); |
505 | if (nf_nat_protos[proto->protonum] != &nf_nat_unknown_protocol) { | 510 | if (rcu_dereference_protected( |
511 | nf_nat_protos[proto->protonum], | ||
512 | lockdep_is_held(&nf_nat_lock) | ||
513 | ) != &nf_nat_unknown_protocol) { | ||
506 | ret = -EBUSY; | 514 | ret = -EBUSY; |
507 | goto out; | 515 | goto out; |
508 | } | 516 | } |
@@ -532,7 +540,7 @@ static void nf_nat_cleanup_conntrack(struct nf_conn *ct) | |||
532 | if (nat == NULL || nat->ct == NULL) | 540 | if (nat == NULL || nat->ct == NULL) |
533 | return; | 541 | return; |
534 | 542 | ||
535 | NF_CT_ASSERT(nat->ct->status & IPS_NAT_DONE_MASK); | 543 | NF_CT_ASSERT(nat->ct->status & IPS_SRC_NAT_DONE); |
536 | 544 | ||
537 | spin_lock_bh(&nf_nat_lock); | 545 | spin_lock_bh(&nf_nat_lock); |
538 | hlist_del_rcu(&nat->bysource); | 546 | hlist_del_rcu(&nat->bysource); |
@@ -545,11 +553,10 @@ static void nf_nat_move_storage(void *new, void *old) | |||
545 | struct nf_conn_nat *old_nat = old; | 553 | struct nf_conn_nat *old_nat = old; |
546 | struct nf_conn *ct = old_nat->ct; | 554 | struct nf_conn *ct = old_nat->ct; |
547 | 555 | ||
548 | if (!ct || !(ct->status & IPS_NAT_DONE_MASK)) | 556 | if (!ct || !(ct->status & IPS_SRC_NAT_DONE)) |
549 | return; | 557 | return; |
550 | 558 | ||
551 | spin_lock_bh(&nf_nat_lock); | 559 | spin_lock_bh(&nf_nat_lock); |
552 | new_nat->ct = ct; | ||
553 | hlist_replace_rcu(&old_nat->bysource, &new_nat->bysource); | 560 | hlist_replace_rcu(&old_nat->bysource, &new_nat->bysource); |
554 | spin_unlock_bh(&nf_nat_lock); | 561 | spin_unlock_bh(&nf_nat_lock); |
555 | } | 562 | } |
@@ -679,8 +686,7 @@ static int __net_init nf_nat_net_init(struct net *net) | |||
679 | { | 686 | { |
680 | /* Leave them the same for the moment. */ | 687 | /* Leave them the same for the moment. */ |
681 | net->ipv4.nat_htable_size = net->ct.htable_size; | 688 | net->ipv4.nat_htable_size = net->ct.htable_size; |
682 | net->ipv4.nat_bysource = nf_ct_alloc_hashtable(&net->ipv4.nat_htable_size, | 689 | net->ipv4.nat_bysource = nf_ct_alloc_hashtable(&net->ipv4.nat_htable_size, 0); |
683 | &net->ipv4.nat_vmalloced, 0); | ||
684 | if (!net->ipv4.nat_bysource) | 690 | if (!net->ipv4.nat_bysource) |
685 | return -ENOMEM; | 691 | return -ENOMEM; |
686 | return 0; | 692 | return 0; |
@@ -702,8 +708,7 @@ static void __net_exit nf_nat_net_exit(struct net *net) | |||
702 | { | 708 | { |
703 | nf_ct_iterate_cleanup(net, &clean_nat, NULL); | 709 | nf_ct_iterate_cleanup(net, &clean_nat, NULL); |
704 | synchronize_rcu(); | 710 | synchronize_rcu(); |
705 | nf_ct_free_hashtable(net->ipv4.nat_bysource, net->ipv4.nat_vmalloced, | 711 | nf_ct_free_hashtable(net->ipv4.nat_bysource, net->ipv4.nat_htable_size); |
706 | net->ipv4.nat_htable_size); | ||
707 | } | 712 | } |
708 | 713 | ||
709 | static struct pernet_operations nf_nat_net_ops = { | 714 | static struct pernet_operations nf_nat_net_ops = { |
diff --git a/net/ipv4/netfilter/nf_nat_snmp_basic.c b/net/ipv4/netfilter/nf_nat_snmp_basic.c index ee5f419d0a56..8812a02078ab 100644 --- a/net/ipv4/netfilter/nf_nat_snmp_basic.c +++ b/net/ipv4/netfilter/nf_nat_snmp_basic.c | |||
@@ -54,6 +54,7 @@ | |||
54 | #include <net/netfilter/nf_conntrack_expect.h> | 54 | #include <net/netfilter/nf_conntrack_expect.h> |
55 | #include <net/netfilter/nf_conntrack_helper.h> | 55 | #include <net/netfilter/nf_conntrack_helper.h> |
56 | #include <net/netfilter/nf_nat_helper.h> | 56 | #include <net/netfilter/nf_nat_helper.h> |
57 | #include <linux/netfilter/nf_conntrack_snmp.h> | ||
57 | 58 | ||
58 | MODULE_LICENSE("GPL"); | 59 | MODULE_LICENSE("GPL"); |
59 | MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>"); | 60 | MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>"); |
@@ -1310,9 +1311,9 @@ static int __init nf_nat_snmp_basic_init(void) | |||
1310 | { | 1311 | { |
1311 | int ret = 0; | 1312 | int ret = 0; |
1312 | 1313 | ||
1313 | ret = nf_conntrack_helper_register(&snmp_helper); | 1314 | BUG_ON(nf_nat_snmp_hook != NULL); |
1314 | if (ret < 0) | 1315 | rcu_assign_pointer(nf_nat_snmp_hook, help); |
1315 | return ret; | 1316 | |
1316 | ret = nf_conntrack_helper_register(&snmp_trap_helper); | 1317 | ret = nf_conntrack_helper_register(&snmp_trap_helper); |
1317 | if (ret < 0) { | 1318 | if (ret < 0) { |
1318 | nf_conntrack_helper_unregister(&snmp_helper); | 1319 | nf_conntrack_helper_unregister(&snmp_helper); |
@@ -1323,7 +1324,7 @@ static int __init nf_nat_snmp_basic_init(void) | |||
1323 | 1324 | ||
1324 | static void __exit nf_nat_snmp_basic_fini(void) | 1325 | static void __exit nf_nat_snmp_basic_fini(void) |
1325 | { | 1326 | { |
1326 | nf_conntrack_helper_unregister(&snmp_helper); | 1327 | rcu_assign_pointer(nf_nat_snmp_hook, NULL); |
1327 | nf_conntrack_helper_unregister(&snmp_trap_helper); | 1328 | nf_conntrack_helper_unregister(&snmp_trap_helper); |
1328 | } | 1329 | } |
1329 | 1330 | ||
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 351dc4e85242..b1e5d3ac3460 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -152,6 +152,41 @@ static void ipv4_dst_ifdown(struct dst_entry *dst, struct net_device *dev, | |||
152 | { | 152 | { |
153 | } | 153 | } |
154 | 154 | ||
155 | static u32 *ipv4_cow_metrics(struct dst_entry *dst, unsigned long old) | ||
156 | { | ||
157 | struct rtable *rt = (struct rtable *) dst; | ||
158 | struct inet_peer *peer; | ||
159 | u32 *p = NULL; | ||
160 | |||
161 | if (!rt->peer) | ||
162 | rt_bind_peer(rt, 1); | ||
163 | |||
164 | peer = rt->peer; | ||
165 | if (peer) { | ||
166 | u32 *old_p = __DST_METRICS_PTR(old); | ||
167 | unsigned long prev, new; | ||
168 | |||
169 | p = peer->metrics; | ||
170 | if (inet_metrics_new(peer)) | ||
171 | memcpy(p, old_p, sizeof(u32) * RTAX_MAX); | ||
172 | |||
173 | new = (unsigned long) p; | ||
174 | prev = cmpxchg(&dst->_metrics, old, new); | ||
175 | |||
176 | if (prev != old) { | ||
177 | p = __DST_METRICS_PTR(prev); | ||
178 | if (prev & DST_METRICS_READ_ONLY) | ||
179 | p = NULL; | ||
180 | } else { | ||
181 | if (rt->fi) { | ||
182 | fib_info_put(rt->fi); | ||
183 | rt->fi = NULL; | ||
184 | } | ||
185 | } | ||
186 | } | ||
187 | return p; | ||
188 | } | ||
189 | |||
155 | static struct dst_ops ipv4_dst_ops = { | 190 | static struct dst_ops ipv4_dst_ops = { |
156 | .family = AF_INET, | 191 | .family = AF_INET, |
157 | .protocol = cpu_to_be16(ETH_P_IP), | 192 | .protocol = cpu_to_be16(ETH_P_IP), |
@@ -159,6 +194,7 @@ static struct dst_ops ipv4_dst_ops = { | |||
159 | .check = ipv4_dst_check, | 194 | .check = ipv4_dst_check, |
160 | .default_advmss = ipv4_default_advmss, | 195 | .default_advmss = ipv4_default_advmss, |
161 | .default_mtu = ipv4_default_mtu, | 196 | .default_mtu = ipv4_default_mtu, |
197 | .cow_metrics = ipv4_cow_metrics, | ||
162 | .destroy = ipv4_dst_destroy, | 198 | .destroy = ipv4_dst_destroy, |
163 | .ifdown = ipv4_dst_ifdown, | 199 | .ifdown = ipv4_dst_ifdown, |
164 | .negative_advice = ipv4_negative_advice, | 200 | .negative_advice = ipv4_negative_advice, |
@@ -514,7 +550,7 @@ static const struct file_operations rt_cpu_seq_fops = { | |||
514 | .release = seq_release, | 550 | .release = seq_release, |
515 | }; | 551 | }; |
516 | 552 | ||
517 | #ifdef CONFIG_NET_CLS_ROUTE | 553 | #ifdef CONFIG_IP_ROUTE_CLASSID |
518 | static int rt_acct_proc_show(struct seq_file *m, void *v) | 554 | static int rt_acct_proc_show(struct seq_file *m, void *v) |
519 | { | 555 | { |
520 | struct ip_rt_acct *dst, *src; | 556 | struct ip_rt_acct *dst, *src; |
@@ -567,14 +603,14 @@ static int __net_init ip_rt_do_proc_init(struct net *net) | |||
567 | if (!pde) | 603 | if (!pde) |
568 | goto err2; | 604 | goto err2; |
569 | 605 | ||
570 | #ifdef CONFIG_NET_CLS_ROUTE | 606 | #ifdef CONFIG_IP_ROUTE_CLASSID |
571 | pde = proc_create("rt_acct", 0, net->proc_net, &rt_acct_proc_fops); | 607 | pde = proc_create("rt_acct", 0, net->proc_net, &rt_acct_proc_fops); |
572 | if (!pde) | 608 | if (!pde) |
573 | goto err3; | 609 | goto err3; |
574 | #endif | 610 | #endif |
575 | return 0; | 611 | return 0; |
576 | 612 | ||
577 | #ifdef CONFIG_NET_CLS_ROUTE | 613 | #ifdef CONFIG_IP_ROUTE_CLASSID |
578 | err3: | 614 | err3: |
579 | remove_proc_entry("rt_cache", net->proc_net_stat); | 615 | remove_proc_entry("rt_cache", net->proc_net_stat); |
580 | #endif | 616 | #endif |
@@ -588,7 +624,7 @@ static void __net_exit ip_rt_do_proc_exit(struct net *net) | |||
588 | { | 624 | { |
589 | remove_proc_entry("rt_cache", net->proc_net_stat); | 625 | remove_proc_entry("rt_cache", net->proc_net_stat); |
590 | remove_proc_entry("rt_cache", net->proc_net); | 626 | remove_proc_entry("rt_cache", net->proc_net); |
591 | #ifdef CONFIG_NET_CLS_ROUTE | 627 | #ifdef CONFIG_IP_ROUTE_CLASSID |
592 | remove_proc_entry("rt_acct", net->proc_net); | 628 | remove_proc_entry("rt_acct", net->proc_net); |
593 | #endif | 629 | #endif |
594 | } | 630 | } |
@@ -1441,6 +1477,8 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, | |||
1441 | 1477 | ||
1442 | if (rt->peer) | 1478 | if (rt->peer) |
1443 | atomic_inc(&rt->peer->refcnt); | 1479 | atomic_inc(&rt->peer->refcnt); |
1480 | if (rt->fi) | ||
1481 | atomic_inc(&rt->fi->fib_clntref); | ||
1444 | 1482 | ||
1445 | if (arp_bind_neighbour(&rt->dst) || | 1483 | if (arp_bind_neighbour(&rt->dst) || |
1446 | !(rt->dst.neighbour->nud_state & | 1484 | !(rt->dst.neighbour->nud_state & |
@@ -1720,6 +1758,10 @@ static void ipv4_dst_destroy(struct dst_entry *dst) | |||
1720 | struct rtable *rt = (struct rtable *) dst; | 1758 | struct rtable *rt = (struct rtable *) dst; |
1721 | struct inet_peer *peer = rt->peer; | 1759 | struct inet_peer *peer = rt->peer; |
1722 | 1760 | ||
1761 | if (rt->fi) { | ||
1762 | fib_info_put(rt->fi); | ||
1763 | rt->fi = NULL; | ||
1764 | } | ||
1723 | if (peer) { | 1765 | if (peer) { |
1724 | rt->peer = NULL; | 1766 | rt->peer = NULL; |
1725 | inet_putpeer(peer); | 1767 | inet_putpeer(peer); |
@@ -1775,7 +1817,7 @@ void ip_rt_get_source(u8 *addr, struct rtable *rt) | |||
1775 | memcpy(addr, &src, 4); | 1817 | memcpy(addr, &src, 4); |
1776 | } | 1818 | } |
1777 | 1819 | ||
1778 | #ifdef CONFIG_NET_CLS_ROUTE | 1820 | #ifdef CONFIG_IP_ROUTE_CLASSID |
1779 | static void set_class_tag(struct rtable *rt, u32 tag) | 1821 | static void set_class_tag(struct rtable *rt, u32 tag) |
1780 | { | 1822 | { |
1781 | if (!(rt->dst.tclassid & 0xFFFF)) | 1823 | if (!(rt->dst.tclassid & 0xFFFF)) |
@@ -1815,6 +1857,30 @@ static unsigned int ipv4_default_mtu(const struct dst_entry *dst) | |||
1815 | return mtu; | 1857 | return mtu; |
1816 | } | 1858 | } |
1817 | 1859 | ||
1860 | static void rt_init_metrics(struct rtable *rt, struct fib_info *fi) | ||
1861 | { | ||
1862 | if (!(rt->fl.flags & FLOWI_FLAG_PRECOW_METRICS)) { | ||
1863 | no_cow: | ||
1864 | if (fi->fib_metrics != (u32 *) dst_default_metrics) { | ||
1865 | rt->fi = fi; | ||
1866 | atomic_inc(&fi->fib_clntref); | ||
1867 | } | ||
1868 | dst_init_metrics(&rt->dst, fi->fib_metrics, true); | ||
1869 | } else { | ||
1870 | struct inet_peer *peer; | ||
1871 | |||
1872 | if (!rt->peer) | ||
1873 | rt_bind_peer(rt, 1); | ||
1874 | peer = rt->peer; | ||
1875 | if (!peer) | ||
1876 | goto no_cow; | ||
1877 | if (inet_metrics_new(peer)) | ||
1878 | memcpy(peer->metrics, fi->fib_metrics, | ||
1879 | sizeof(u32) * RTAX_MAX); | ||
1880 | dst_init_metrics(&rt->dst, peer->metrics, false); | ||
1881 | } | ||
1882 | } | ||
1883 | |||
1818 | static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag) | 1884 | static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag) |
1819 | { | 1885 | { |
1820 | struct dst_entry *dst = &rt->dst; | 1886 | struct dst_entry *dst = &rt->dst; |
@@ -1824,8 +1890,8 @@ static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag) | |||
1824 | if (FIB_RES_GW(*res) && | 1890 | if (FIB_RES_GW(*res) && |
1825 | FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK) | 1891 | FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK) |
1826 | rt->rt_gateway = FIB_RES_GW(*res); | 1892 | rt->rt_gateway = FIB_RES_GW(*res); |
1827 | dst_import_metrics(dst, fi->fib_metrics); | 1893 | rt_init_metrics(rt, fi); |
1828 | #ifdef CONFIG_NET_CLS_ROUTE | 1894 | #ifdef CONFIG_IP_ROUTE_CLASSID |
1829 | dst->tclassid = FIB_RES_NH(*res).nh_tclassid; | 1895 | dst->tclassid = FIB_RES_NH(*res).nh_tclassid; |
1830 | #endif | 1896 | #endif |
1831 | } | 1897 | } |
@@ -1835,7 +1901,7 @@ static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag) | |||
1835 | if (dst_metric_raw(dst, RTAX_ADVMSS) > 65535 - 40) | 1901 | if (dst_metric_raw(dst, RTAX_ADVMSS) > 65535 - 40) |
1836 | dst_metric_set(dst, RTAX_ADVMSS, 65535 - 40); | 1902 | dst_metric_set(dst, RTAX_ADVMSS, 65535 - 40); |
1837 | 1903 | ||
1838 | #ifdef CONFIG_NET_CLS_ROUTE | 1904 | #ifdef CONFIG_IP_ROUTE_CLASSID |
1839 | #ifdef CONFIG_IP_MULTIPLE_TABLES | 1905 | #ifdef CONFIG_IP_MULTIPLE_TABLES |
1840 | set_class_tag(rt, fib_rules_tclass(res)); | 1906 | set_class_tag(rt, fib_rules_tclass(res)); |
1841 | #endif | 1907 | #endif |
@@ -1891,7 +1957,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
1891 | rth->fl.mark = skb->mark; | 1957 | rth->fl.mark = skb->mark; |
1892 | rth->fl.fl4_src = saddr; | 1958 | rth->fl.fl4_src = saddr; |
1893 | rth->rt_src = saddr; | 1959 | rth->rt_src = saddr; |
1894 | #ifdef CONFIG_NET_CLS_ROUTE | 1960 | #ifdef CONFIG_IP_ROUTE_CLASSID |
1895 | rth->dst.tclassid = itag; | 1961 | rth->dst.tclassid = itag; |
1896 | #endif | 1962 | #endif |
1897 | rth->rt_iif = | 1963 | rth->rt_iif = |
@@ -2208,7 +2274,7 @@ local_input: | |||
2208 | rth->fl.mark = skb->mark; | 2274 | rth->fl.mark = skb->mark; |
2209 | rth->fl.fl4_src = saddr; | 2275 | rth->fl.fl4_src = saddr; |
2210 | rth->rt_src = saddr; | 2276 | rth->rt_src = saddr; |
2211 | #ifdef CONFIG_NET_CLS_ROUTE | 2277 | #ifdef CONFIG_IP_ROUTE_CLASSID |
2212 | rth->dst.tclassid = itag; | 2278 | rth->dst.tclassid = itag; |
2213 | #endif | 2279 | #endif |
2214 | rth->rt_iif = | 2280 | rth->rt_iif = |
@@ -2752,6 +2818,9 @@ static int ipv4_dst_blackhole(struct net *net, struct rtable **rp, struct flowi | |||
2752 | rt->peer = ort->peer; | 2818 | rt->peer = ort->peer; |
2753 | if (rt->peer) | 2819 | if (rt->peer) |
2754 | atomic_inc(&rt->peer->refcnt); | 2820 | atomic_inc(&rt->peer->refcnt); |
2821 | rt->fi = ort->fi; | ||
2822 | if (rt->fi) | ||
2823 | atomic_inc(&rt->fi->fib_clntref); | ||
2755 | 2824 | ||
2756 | dst_free(new); | 2825 | dst_free(new); |
2757 | } | 2826 | } |
@@ -2828,7 +2897,7 @@ static int rt_fill_info(struct net *net, | |||
2828 | } | 2897 | } |
2829 | if (rt->dst.dev) | 2898 | if (rt->dst.dev) |
2830 | NLA_PUT_U32(skb, RTA_OIF, rt->dst.dev->ifindex); | 2899 | NLA_PUT_U32(skb, RTA_OIF, rt->dst.dev->ifindex); |
2831 | #ifdef CONFIG_NET_CLS_ROUTE | 2900 | #ifdef CONFIG_IP_ROUTE_CLASSID |
2832 | if (rt->dst.tclassid) | 2901 | if (rt->dst.tclassid) |
2833 | NLA_PUT_U32(skb, RTA_FLOW, rt->dst.tclassid); | 2902 | NLA_PUT_U32(skb, RTA_FLOW, rt->dst.tclassid); |
2834 | #endif | 2903 | #endif |
@@ -3249,9 +3318,9 @@ static __net_initdata struct pernet_operations rt_genid_ops = { | |||
3249 | }; | 3318 | }; |
3250 | 3319 | ||
3251 | 3320 | ||
3252 | #ifdef CONFIG_NET_CLS_ROUTE | 3321 | #ifdef CONFIG_IP_ROUTE_CLASSID |
3253 | struct ip_rt_acct __percpu *ip_rt_acct __read_mostly; | 3322 | struct ip_rt_acct __percpu *ip_rt_acct __read_mostly; |
3254 | #endif /* CONFIG_NET_CLS_ROUTE */ | 3323 | #endif /* CONFIG_IP_ROUTE_CLASSID */ |
3255 | 3324 | ||
3256 | static __initdata unsigned long rhash_entries; | 3325 | static __initdata unsigned long rhash_entries; |
3257 | static int __init set_rhash_entries(char *str) | 3326 | static int __init set_rhash_entries(char *str) |
@@ -3267,7 +3336,7 @@ int __init ip_rt_init(void) | |||
3267 | { | 3336 | { |
3268 | int rc = 0; | 3337 | int rc = 0; |
3269 | 3338 | ||
3270 | #ifdef CONFIG_NET_CLS_ROUTE | 3339 | #ifdef CONFIG_IP_ROUTE_CLASSID |
3271 | ip_rt_acct = __alloc_percpu(256 * sizeof(struct ip_rt_acct), __alignof__(struct ip_rt_acct)); | 3340 | ip_rt_acct = __alloc_percpu(256 * sizeof(struct ip_rt_acct), __alignof__(struct ip_rt_acct)); |
3272 | if (!ip_rt_acct) | 3341 | if (!ip_rt_acct) |
3273 | panic("IP: failed to allocate ip_rt_acct\n"); | 3342 | panic("IP: failed to allocate ip_rt_acct\n"); |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 6c11eece262c..f9867d2dbef4 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -2653,7 +2653,7 @@ int compat_tcp_getsockopt(struct sock *sk, int level, int optname, | |||
2653 | EXPORT_SYMBOL(compat_tcp_getsockopt); | 2653 | EXPORT_SYMBOL(compat_tcp_getsockopt); |
2654 | #endif | 2654 | #endif |
2655 | 2655 | ||
2656 | struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features) | 2656 | struct sk_buff *tcp_tso_segment(struct sk_buff *skb, u32 features) |
2657 | { | 2657 | { |
2658 | struct sk_buff *segs = ERR_PTR(-EINVAL); | 2658 | struct sk_buff *segs = ERR_PTR(-EINVAL); |
2659 | struct tcphdr *th; | 2659 | struct tcphdr *th; |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 8157b17959ee..d37baaa1dbe3 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -2199,7 +2199,7 @@ int udp4_ufo_send_check(struct sk_buff *skb) | |||
2199 | return 0; | 2199 | return 0; |
2200 | } | 2200 | } |
2201 | 2201 | ||
2202 | struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb, int features) | 2202 | struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb, u32 features) |
2203 | { | 2203 | { |
2204 | struct sk_buff *segs = ERR_PTR(-EINVAL); | 2204 | struct sk_buff *segs = ERR_PTR(-EINVAL); |
2205 | unsigned int mss; | 2205 | unsigned int mss; |
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index b057d40addec..19fbdec6baaa 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c | |||
@@ -196,8 +196,11 @@ static void xfrm4_dst_destroy(struct dst_entry *dst) | |||
196 | { | 196 | { |
197 | struct xfrm_dst *xdst = (struct xfrm_dst *)dst; | 197 | struct xfrm_dst *xdst = (struct xfrm_dst *)dst; |
198 | 198 | ||
199 | dst_destroy_metrics_generic(dst); | ||
200 | |||
199 | if (likely(xdst->u.rt.peer)) | 201 | if (likely(xdst->u.rt.peer)) |
200 | inet_putpeer(xdst->u.rt.peer); | 202 | inet_putpeer(xdst->u.rt.peer); |
203 | |||
201 | xfrm_dst_destroy(xdst); | 204 | xfrm_dst_destroy(xdst); |
202 | } | 205 | } |
203 | 206 | ||
@@ -215,6 +218,7 @@ static struct dst_ops xfrm4_dst_ops = { | |||
215 | .protocol = cpu_to_be16(ETH_P_IP), | 218 | .protocol = cpu_to_be16(ETH_P_IP), |
216 | .gc = xfrm4_garbage_collect, | 219 | .gc = xfrm4_garbage_collect, |
217 | .update_pmtu = xfrm4_update_pmtu, | 220 | .update_pmtu = xfrm4_update_pmtu, |
221 | .cow_metrics = dst_cow_metrics_generic, | ||
218 | .destroy = xfrm4_dst_destroy, | 222 | .destroy = xfrm4_dst_destroy, |
219 | .ifdown = xfrm4_dst_ifdown, | 223 | .ifdown = xfrm4_dst_ifdown, |
220 | .local_out = __ip_local_out, | 224 | .local_out = __ip_local_out, |