diff options
-rw-r--r-- | include/linux/snmp.h | 2 | ||||
-rw-r--r-- | include/net/icmp.h | 8 | ||||
-rw-r--r-- | include/net/snmp.h | 5 | ||||
-rw-r--r-- | net/ipv4/af_inet.c | 6 | ||||
-rw-r--r-- | net/ipv4/icmp.c | 53 | ||||
-rw-r--r-- | net/ipv4/ip_output.c | 4 | ||||
-rw-r--r-- | net/ipv4/proc.c | 120 | ||||
-rw-r--r-- | net/ipv4/raw.c | 3 |
8 files changed, 123 insertions, 78 deletions
diff --git a/include/linux/snmp.h b/include/linux/snmp.h index 86977e31548a..d8fd3ec4148a 100644 --- a/include/linux/snmp.h +++ b/include/linux/snmp.h | |||
@@ -82,6 +82,8 @@ enum | |||
82 | __ICMP_MIB_MAX | 82 | __ICMP_MIB_MAX |
83 | }; | 83 | }; |
84 | 84 | ||
85 | #define __ICMPMSG_MIB_MAX 512 /* Out+In for all 8-bit ICMP types */ | ||
86 | |||
85 | /* icmp6 mib definitions */ | 87 | /* icmp6 mib definitions */ |
86 | /* | 88 | /* |
87 | * RFC 2466: ICMPv6-MIB | 89 | * RFC 2466: ICMPv6-MIB |
diff --git a/include/net/icmp.h b/include/net/icmp.h index dc09474efcf3..9f7ef3c8baef 100644 --- a/include/net/icmp.h +++ b/include/net/icmp.h | |||
@@ -30,9 +30,16 @@ struct icmp_err { | |||
30 | 30 | ||
31 | extern struct icmp_err icmp_err_convert[]; | 31 | extern struct icmp_err icmp_err_convert[]; |
32 | DECLARE_SNMP_STAT(struct icmp_mib, icmp_statistics); | 32 | DECLARE_SNMP_STAT(struct icmp_mib, icmp_statistics); |
33 | DECLARE_SNMP_STAT(struct icmpmsg_mib, icmpmsg_statistics); | ||
33 | #define ICMP_INC_STATS(field) SNMP_INC_STATS(icmp_statistics, field) | 34 | #define ICMP_INC_STATS(field) SNMP_INC_STATS(icmp_statistics, field) |
34 | #define ICMP_INC_STATS_BH(field) SNMP_INC_STATS_BH(icmp_statistics, field) | 35 | #define ICMP_INC_STATS_BH(field) SNMP_INC_STATS_BH(icmp_statistics, field) |
35 | #define ICMP_INC_STATS_USER(field) SNMP_INC_STATS_USER(icmp_statistics, field) | 36 | #define ICMP_INC_STATS_USER(field) SNMP_INC_STATS_USER(icmp_statistics, field) |
37 | #define ICMPMSGOUT_INC_STATS(field) SNMP_INC_STATS(icmpmsg_statistics, field+256) | ||
38 | #define ICMPMSGOUT_INC_STATS_BH(field) SNMP_INC_STATS_BH(icmpmsg_statistics, field+256) | ||
39 | #define ICMPMSGOUT_INC_STATS_USER(field) SNMP_INC_STATS_USER(icmpmsg_statistics, field+256) | ||
40 | #define ICMPMSGIN_INC_STATS(field) SNMP_INC_STATS(icmpmsg_statistics, field) | ||
41 | #define ICMPMSGIN_INC_STATS_BH(field) SNMP_INC_STATS_BH(icmpmsg_statistics, field) | ||
42 | #define ICMPMSGIN_INC_STATS_USER(field) SNMP_INC_STATS_USER(icmpmsg_statistics, field) | ||
36 | 43 | ||
37 | struct dst_entry; | 44 | struct dst_entry; |
38 | struct net_proto_family; | 45 | struct net_proto_family; |
@@ -42,6 +49,7 @@ extern void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info); | |||
42 | extern int icmp_rcv(struct sk_buff *skb); | 49 | extern int icmp_rcv(struct sk_buff *skb); |
43 | extern int icmp_ioctl(struct sock *sk, int cmd, unsigned long arg); | 50 | extern int icmp_ioctl(struct sock *sk, int cmd, unsigned long arg); |
44 | extern void icmp_init(struct net_proto_family *ops); | 51 | extern void icmp_init(struct net_proto_family *ops); |
52 | extern void icmp_out_count(unsigned char type); | ||
45 | 53 | ||
46 | /* Move into dst.h ? */ | 54 | /* Move into dst.h ? */ |
47 | extern int xrlim_allow(struct dst_entry *dst, int timeout); | 55 | extern int xrlim_allow(struct dst_entry *dst, int timeout); |
diff --git a/include/net/snmp.h b/include/net/snmp.h index a566e11d2f98..ea206bff0dc4 100644 --- a/include/net/snmp.h +++ b/include/net/snmp.h | |||
@@ -82,6 +82,11 @@ struct icmp_mib { | |||
82 | unsigned long mibs[ICMP_MIB_MAX]; | 82 | unsigned long mibs[ICMP_MIB_MAX]; |
83 | } __SNMP_MIB_ALIGN__; | 83 | } __SNMP_MIB_ALIGN__; |
84 | 84 | ||
85 | #define ICMPMSG_MIB_MAX __ICMPMSG_MIB_MAX | ||
86 | struct icmpmsg_mib { | ||
87 | unsigned long mibs[ICMPMSG_MIB_MAX]; | ||
88 | } __SNMP_MIB_ALIGN__; | ||
89 | |||
85 | /* ICMP6 (IPv6-ICMP) */ | 90 | /* ICMP6 (IPv6-ICMP) */ |
86 | #define ICMP6_MIB_MAX __ICMP6_MIB_MAX | 91 | #define ICMP6_MIB_MAX __ICMP6_MIB_MAX |
87 | struct icmpv6_mib { | 92 | struct icmpv6_mib { |
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index e594a2c89661..621b128897d7 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
@@ -1302,6 +1302,10 @@ static int __init init_ipv4_mibs(void) | |||
1302 | sizeof(struct icmp_mib), | 1302 | sizeof(struct icmp_mib), |
1303 | __alignof__(struct icmp_mib)) < 0) | 1303 | __alignof__(struct icmp_mib)) < 0) |
1304 | goto err_icmp_mib; | 1304 | goto err_icmp_mib; |
1305 | if (snmp_mib_init((void **)icmpmsg_statistics, | ||
1306 | sizeof(struct icmpmsg_mib), | ||
1307 | __alignof__(struct icmpmsg_mib)) < 0) | ||
1308 | goto err_icmpmsg_mib; | ||
1305 | if (snmp_mib_init((void **)tcp_statistics, | 1309 | if (snmp_mib_init((void **)tcp_statistics, |
1306 | sizeof(struct tcp_mib), | 1310 | sizeof(struct tcp_mib), |
1307 | __alignof__(struct tcp_mib)) < 0) | 1311 | __alignof__(struct tcp_mib)) < 0) |
@@ -1324,6 +1328,8 @@ err_udplite_mib: | |||
1324 | err_udp_mib: | 1328 | err_udp_mib: |
1325 | snmp_mib_free((void **)tcp_statistics); | 1329 | snmp_mib_free((void **)tcp_statistics); |
1326 | err_tcp_mib: | 1330 | err_tcp_mib: |
1331 | snmp_mib_free((void **)icmpmsg_statistics); | ||
1332 | err_icmpmsg_mib: | ||
1327 | snmp_mib_free((void **)icmp_statistics); | 1333 | snmp_mib_free((void **)icmp_statistics); |
1328 | err_icmp_mib: | 1334 | err_icmp_mib: |
1329 | snmp_mib_free((void **)ip_statistics); | 1335 | snmp_mib_free((void **)ip_statistics); |
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 68a22670f597..272c69e106e9 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c | |||
@@ -115,6 +115,7 @@ struct icmp_bxm { | |||
115 | * Statistics | 115 | * Statistics |
116 | */ | 116 | */ |
117 | DEFINE_SNMP_STAT(struct icmp_mib, icmp_statistics) __read_mostly; | 117 | DEFINE_SNMP_STAT(struct icmp_mib, icmp_statistics) __read_mostly; |
118 | DEFINE_SNMP_STAT(struct icmpmsg_mib, icmpmsg_statistics) __read_mostly; | ||
118 | 119 | ||
119 | /* An array of errno for error messages from dest unreach. */ | 120 | /* An array of errno for error messages from dest unreach. */ |
120 | /* RFC 1122: 3.2.2.1 States that NET_UNREACH, HOST_UNREACH and SR_FAILED MUST be considered 'transient errs'. */ | 121 | /* RFC 1122: 3.2.2.1 States that NET_UNREACH, HOST_UNREACH and SR_FAILED MUST be considered 'transient errs'. */ |
@@ -214,8 +215,6 @@ int sysctl_icmp_errors_use_inbound_ifaddr __read_mostly; | |||
214 | */ | 215 | */ |
215 | 216 | ||
216 | struct icmp_control { | 217 | struct icmp_control { |
217 | int output_entry; /* Field for increment on output */ | ||
218 | int input_entry; /* Field for increment on input */ | ||
219 | void (*handler)(struct sk_buff *skb); | 218 | void (*handler)(struct sk_buff *skb); |
220 | short error; /* This ICMP is classed as an error message */ | 219 | short error; /* This ICMP is classed as an error message */ |
221 | }; | 220 | }; |
@@ -316,12 +315,10 @@ out: | |||
316 | /* | 315 | /* |
317 | * Maintain the counters used in the SNMP statistics for outgoing ICMP | 316 | * Maintain the counters used in the SNMP statistics for outgoing ICMP |
318 | */ | 317 | */ |
319 | static void icmp_out_count(int type) | 318 | void icmp_out_count(unsigned char type) |
320 | { | 319 | { |
321 | if (type <= NR_ICMP_TYPES) { | 320 | ICMPMSGOUT_INC_STATS(type); |
322 | ICMP_INC_STATS(icmp_pointers[type].output_entry); | 321 | ICMP_INC_STATS(ICMP_MIB_OUTMSGS); |
323 | ICMP_INC_STATS(ICMP_MIB_OUTMSGS); | ||
324 | } | ||
325 | } | 322 | } |
326 | 323 | ||
327 | /* | 324 | /* |
@@ -390,7 +387,6 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) | |||
390 | return; | 387 | return; |
391 | 388 | ||
392 | icmp_param->data.icmph.checksum = 0; | 389 | icmp_param->data.icmph.checksum = 0; |
393 | icmp_out_count(icmp_param->data.icmph.type); | ||
394 | 390 | ||
395 | inet->tos = ip_hdr(skb)->tos; | 391 | inet->tos = ip_hdr(skb)->tos; |
396 | daddr = ipc.addr = rt->rt_src; | 392 | daddr = ipc.addr = rt->rt_src; |
@@ -952,6 +948,7 @@ int icmp_rcv(struct sk_buff *skb) | |||
952 | 948 | ||
953 | icmph = icmp_hdr(skb); | 949 | icmph = icmp_hdr(skb); |
954 | 950 | ||
951 | ICMPMSGIN_INC_STATS_BH(icmph->type); | ||
955 | /* | 952 | /* |
956 | * 18 is the highest 'known' ICMP type. Anything else is a mystery | 953 | * 18 is the highest 'known' ICMP type. Anything else is a mystery |
957 | * | 954 | * |
@@ -986,7 +983,6 @@ int icmp_rcv(struct sk_buff *skb) | |||
986 | } | 983 | } |
987 | } | 984 | } |
988 | 985 | ||
989 | ICMP_INC_STATS_BH(icmp_pointers[icmph->type].input_entry); | ||
990 | icmp_pointers[icmph->type].handler(skb); | 986 | icmp_pointers[icmph->type].handler(skb); |
991 | 987 | ||
992 | drop: | 988 | drop: |
@@ -1002,109 +998,71 @@ error: | |||
1002 | */ | 998 | */ |
1003 | static const struct icmp_control icmp_pointers[NR_ICMP_TYPES + 1] = { | 999 | static const struct icmp_control icmp_pointers[NR_ICMP_TYPES + 1] = { |
1004 | [ICMP_ECHOREPLY] = { | 1000 | [ICMP_ECHOREPLY] = { |
1005 | .output_entry = ICMP_MIB_OUTECHOREPS, | ||
1006 | .input_entry = ICMP_MIB_INECHOREPS, | ||
1007 | .handler = icmp_discard, | 1001 | .handler = icmp_discard, |
1008 | }, | 1002 | }, |
1009 | [1] = { | 1003 | [1] = { |
1010 | .output_entry = ICMP_MIB_DUMMY, | ||
1011 | .input_entry = ICMP_MIB_INERRORS, | ||
1012 | .handler = icmp_discard, | 1004 | .handler = icmp_discard, |
1013 | .error = 1, | 1005 | .error = 1, |
1014 | }, | 1006 | }, |
1015 | [2] = { | 1007 | [2] = { |
1016 | .output_entry = ICMP_MIB_DUMMY, | ||
1017 | .input_entry = ICMP_MIB_INERRORS, | ||
1018 | .handler = icmp_discard, | 1008 | .handler = icmp_discard, |
1019 | .error = 1, | 1009 | .error = 1, |
1020 | }, | 1010 | }, |
1021 | [ICMP_DEST_UNREACH] = { | 1011 | [ICMP_DEST_UNREACH] = { |
1022 | .output_entry = ICMP_MIB_OUTDESTUNREACHS, | ||
1023 | .input_entry = ICMP_MIB_INDESTUNREACHS, | ||
1024 | .handler = icmp_unreach, | 1012 | .handler = icmp_unreach, |
1025 | .error = 1, | 1013 | .error = 1, |
1026 | }, | 1014 | }, |
1027 | [ICMP_SOURCE_QUENCH] = { | 1015 | [ICMP_SOURCE_QUENCH] = { |
1028 | .output_entry = ICMP_MIB_OUTSRCQUENCHS, | ||
1029 | .input_entry = ICMP_MIB_INSRCQUENCHS, | ||
1030 | .handler = icmp_unreach, | 1016 | .handler = icmp_unreach, |
1031 | .error = 1, | 1017 | .error = 1, |
1032 | }, | 1018 | }, |
1033 | [ICMP_REDIRECT] = { | 1019 | [ICMP_REDIRECT] = { |
1034 | .output_entry = ICMP_MIB_OUTREDIRECTS, | ||
1035 | .input_entry = ICMP_MIB_INREDIRECTS, | ||
1036 | .handler = icmp_redirect, | 1020 | .handler = icmp_redirect, |
1037 | .error = 1, | 1021 | .error = 1, |
1038 | }, | 1022 | }, |
1039 | [6] = { | 1023 | [6] = { |
1040 | .output_entry = ICMP_MIB_DUMMY, | ||
1041 | .input_entry = ICMP_MIB_INERRORS, | ||
1042 | .handler = icmp_discard, | 1024 | .handler = icmp_discard, |
1043 | .error = 1, | 1025 | .error = 1, |
1044 | }, | 1026 | }, |
1045 | [7] = { | 1027 | [7] = { |
1046 | .output_entry = ICMP_MIB_DUMMY, | ||
1047 | .input_entry = ICMP_MIB_INERRORS, | ||
1048 | .handler = icmp_discard, | 1028 | .handler = icmp_discard, |
1049 | .error = 1, | 1029 | .error = 1, |
1050 | }, | 1030 | }, |
1051 | [ICMP_ECHO] = { | 1031 | [ICMP_ECHO] = { |
1052 | .output_entry = ICMP_MIB_OUTECHOS, | ||
1053 | .input_entry = ICMP_MIB_INECHOS, | ||
1054 | .handler = icmp_echo, | 1032 | .handler = icmp_echo, |
1055 | }, | 1033 | }, |
1056 | [9] = { | 1034 | [9] = { |
1057 | .output_entry = ICMP_MIB_DUMMY, | ||
1058 | .input_entry = ICMP_MIB_INERRORS, | ||
1059 | .handler = icmp_discard, | 1035 | .handler = icmp_discard, |
1060 | .error = 1, | 1036 | .error = 1, |
1061 | }, | 1037 | }, |
1062 | [10] = { | 1038 | [10] = { |
1063 | .output_entry = ICMP_MIB_DUMMY, | ||
1064 | .input_entry = ICMP_MIB_INERRORS, | ||
1065 | .handler = icmp_discard, | 1039 | .handler = icmp_discard, |
1066 | .error = 1, | 1040 | .error = 1, |
1067 | }, | 1041 | }, |
1068 | [ICMP_TIME_EXCEEDED] = { | 1042 | [ICMP_TIME_EXCEEDED] = { |
1069 | .output_entry = ICMP_MIB_OUTTIMEEXCDS, | ||
1070 | .input_entry = ICMP_MIB_INTIMEEXCDS, | ||
1071 | .handler = icmp_unreach, | 1043 | .handler = icmp_unreach, |
1072 | .error = 1, | 1044 | .error = 1, |
1073 | }, | 1045 | }, |
1074 | [ICMP_PARAMETERPROB] = { | 1046 | [ICMP_PARAMETERPROB] = { |
1075 | .output_entry = ICMP_MIB_OUTPARMPROBS, | ||
1076 | .input_entry = ICMP_MIB_INPARMPROBS, | ||
1077 | .handler = icmp_unreach, | 1047 | .handler = icmp_unreach, |
1078 | .error = 1, | 1048 | .error = 1, |
1079 | }, | 1049 | }, |
1080 | [ICMP_TIMESTAMP] = { | 1050 | [ICMP_TIMESTAMP] = { |
1081 | .output_entry = ICMP_MIB_OUTTIMESTAMPS, | ||
1082 | .input_entry = ICMP_MIB_INTIMESTAMPS, | ||
1083 | .handler = icmp_timestamp, | 1051 | .handler = icmp_timestamp, |
1084 | }, | 1052 | }, |
1085 | [ICMP_TIMESTAMPREPLY] = { | 1053 | [ICMP_TIMESTAMPREPLY] = { |
1086 | .output_entry = ICMP_MIB_OUTTIMESTAMPREPS, | ||
1087 | .input_entry = ICMP_MIB_INTIMESTAMPREPS, | ||
1088 | .handler = icmp_discard, | 1054 | .handler = icmp_discard, |
1089 | }, | 1055 | }, |
1090 | [ICMP_INFO_REQUEST] = { | 1056 | [ICMP_INFO_REQUEST] = { |
1091 | .output_entry = ICMP_MIB_DUMMY, | ||
1092 | .input_entry = ICMP_MIB_DUMMY, | ||
1093 | .handler = icmp_discard, | 1057 | .handler = icmp_discard, |
1094 | }, | 1058 | }, |
1095 | [ICMP_INFO_REPLY] = { | 1059 | [ICMP_INFO_REPLY] = { |
1096 | .output_entry = ICMP_MIB_DUMMY, | ||
1097 | .input_entry = ICMP_MIB_DUMMY, | ||
1098 | .handler = icmp_discard, | 1060 | .handler = icmp_discard, |
1099 | }, | 1061 | }, |
1100 | [ICMP_ADDRESS] = { | 1062 | [ICMP_ADDRESS] = { |
1101 | .output_entry = ICMP_MIB_OUTADDRMASKS, | ||
1102 | .input_entry = ICMP_MIB_INADDRMASKS, | ||
1103 | .handler = icmp_address, | 1063 | .handler = icmp_address, |
1104 | }, | 1064 | }, |
1105 | [ICMP_ADDRESSREPLY] = { | 1065 | [ICMP_ADDRESSREPLY] = { |
1106 | .output_entry = ICMP_MIB_OUTADDRMASKREPS, | ||
1107 | .input_entry = ICMP_MIB_INADDRMASKREPS, | ||
1108 | .handler = icmp_address_reply, | 1066 | .handler = icmp_address_reply, |
1109 | }, | 1067 | }, |
1110 | }; | 1068 | }; |
@@ -1146,4 +1104,5 @@ void __init icmp_init(struct net_proto_family *ops) | |||
1146 | EXPORT_SYMBOL(icmp_err_convert); | 1104 | EXPORT_SYMBOL(icmp_err_convert); |
1147 | EXPORT_SYMBOL(icmp_send); | 1105 | EXPORT_SYMBOL(icmp_send); |
1148 | EXPORT_SYMBOL(icmp_statistics); | 1106 | EXPORT_SYMBOL(icmp_statistics); |
1107 | EXPORT_SYMBOL(icmpmsg_statistics); | ||
1149 | EXPORT_SYMBOL(xrlim_allow); | 1108 | EXPORT_SYMBOL(xrlim_allow); |
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 0f1d7beacf78..77f67b7cb9bf 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -1261,6 +1261,10 @@ int ip_push_pending_frames(struct sock *sk) | |||
1261 | skb->priority = sk->sk_priority; | 1261 | skb->priority = sk->sk_priority; |
1262 | skb->dst = dst_clone(&rt->u.dst); | 1262 | skb->dst = dst_clone(&rt->u.dst); |
1263 | 1263 | ||
1264 | if (iph->protocol == IPPROTO_ICMP) | ||
1265 | icmp_out_count(((struct icmphdr *) | ||
1266 | skb_transport_header(skb))->type); | ||
1267 | |||
1264 | /* Netfilter gets whole the not fragmented skb. */ | 1268 | /* Netfilter gets whole the not fragmented skb. */ |
1265 | err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, | 1269 | err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, |
1266 | skb->dst->dev, dst_output); | 1270 | skb->dst->dev, dst_output); |
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index 95a8f8f2de71..2015148b41a8 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c | |||
@@ -124,33 +124,30 @@ static const struct snmp_mib snmp4_ipextstats_list[] = { | |||
124 | static const struct snmp_mib snmp4_icmp_list[] = { | 124 | static const struct snmp_mib snmp4_icmp_list[] = { |
125 | SNMP_MIB_ITEM("InMsgs", ICMP_MIB_INMSGS), | 125 | SNMP_MIB_ITEM("InMsgs", ICMP_MIB_INMSGS), |
126 | SNMP_MIB_ITEM("InErrors", ICMP_MIB_INERRORS), | 126 | SNMP_MIB_ITEM("InErrors", ICMP_MIB_INERRORS), |
127 | SNMP_MIB_ITEM("InDestUnreachs", ICMP_MIB_INDESTUNREACHS), | ||
128 | SNMP_MIB_ITEM("InTimeExcds", ICMP_MIB_INTIMEEXCDS), | ||
129 | SNMP_MIB_ITEM("InParmProbs", ICMP_MIB_INPARMPROBS), | ||
130 | SNMP_MIB_ITEM("InSrcQuenchs", ICMP_MIB_INSRCQUENCHS), | ||
131 | SNMP_MIB_ITEM("InRedirects", ICMP_MIB_INREDIRECTS), | ||
132 | SNMP_MIB_ITEM("InEchos", ICMP_MIB_INECHOS), | ||
133 | SNMP_MIB_ITEM("InEchoReps", ICMP_MIB_INECHOREPS), | ||
134 | SNMP_MIB_ITEM("InTimestamps", ICMP_MIB_INTIMESTAMPS), | ||
135 | SNMP_MIB_ITEM("InTimestampReps", ICMP_MIB_INTIMESTAMPREPS), | ||
136 | SNMP_MIB_ITEM("InAddrMasks", ICMP_MIB_INADDRMASKS), | ||
137 | SNMP_MIB_ITEM("InAddrMaskReps", ICMP_MIB_INADDRMASKREPS), | ||
138 | SNMP_MIB_ITEM("OutMsgs", ICMP_MIB_OUTMSGS), | 127 | SNMP_MIB_ITEM("OutMsgs", ICMP_MIB_OUTMSGS), |
139 | SNMP_MIB_ITEM("OutErrors", ICMP_MIB_OUTERRORS), | 128 | SNMP_MIB_ITEM("OutErrors", ICMP_MIB_OUTERRORS), |
140 | SNMP_MIB_ITEM("OutDestUnreachs", ICMP_MIB_OUTDESTUNREACHS), | ||
141 | SNMP_MIB_ITEM("OutTimeExcds", ICMP_MIB_OUTTIMEEXCDS), | ||
142 | SNMP_MIB_ITEM("OutParmProbs", ICMP_MIB_OUTPARMPROBS), | ||
143 | SNMP_MIB_ITEM("OutSrcQuenchs", ICMP_MIB_OUTSRCQUENCHS), | ||
144 | SNMP_MIB_ITEM("OutRedirects", ICMP_MIB_OUTREDIRECTS), | ||
145 | SNMP_MIB_ITEM("OutEchos", ICMP_MIB_OUTECHOS), | ||
146 | SNMP_MIB_ITEM("OutEchoReps", ICMP_MIB_OUTECHOREPS), | ||
147 | SNMP_MIB_ITEM("OutTimestamps", ICMP_MIB_OUTTIMESTAMPS), | ||
148 | SNMP_MIB_ITEM("OutTimestampReps", ICMP_MIB_OUTTIMESTAMPREPS), | ||
149 | SNMP_MIB_ITEM("OutAddrMasks", ICMP_MIB_OUTADDRMASKS), | ||
150 | SNMP_MIB_ITEM("OutAddrMaskReps", ICMP_MIB_OUTADDRMASKREPS), | ||
151 | SNMP_MIB_SENTINEL | 129 | SNMP_MIB_SENTINEL |
152 | }; | 130 | }; |
153 | 131 | ||
132 | static struct { | ||
133 | char *name; | ||
134 | int index; | ||
135 | } icmpmibmap[] = { | ||
136 | { "DestUnreachs", ICMP_DEST_UNREACH }, | ||
137 | { "TimeExcds", ICMP_TIME_EXCEEDED }, | ||
138 | { "ParmProbs", ICMP_PARAMETERPROB }, | ||
139 | { "SrcQuenchs", ICMP_SOURCE_QUENCH }, | ||
140 | { "Redirects", ICMP_REDIRECT }, | ||
141 | { "Echos", ICMP_ECHO }, | ||
142 | { "EchoReps", ICMP_ECHOREPLY }, | ||
143 | { "Timestamps", ICMP_TIMESTAMP }, | ||
144 | { "TimestampReps", ICMP_TIMESTAMPREPLY }, | ||
145 | { "AddrMasks", ICMP_ADDRESS }, | ||
146 | { "AddrMaskReps", ICMP_ADDRESSREPLY }, | ||
147 | { 0, 0 } | ||
148 | }; | ||
149 | |||
150 | |||
154 | static const struct snmp_mib snmp4_tcp_list[] = { | 151 | static const struct snmp_mib snmp4_tcp_list[] = { |
155 | SNMP_MIB_ITEM("RtoAlgorithm", TCP_MIB_RTOALGORITHM), | 152 | SNMP_MIB_ITEM("RtoAlgorithm", TCP_MIB_RTOALGORITHM), |
156 | SNMP_MIB_ITEM("RtoMin", TCP_MIB_RTOMIN), | 153 | SNMP_MIB_ITEM("RtoMin", TCP_MIB_RTOMIN), |
@@ -251,6 +248,72 @@ static const struct snmp_mib snmp4_net_list[] = { | |||
251 | SNMP_MIB_SENTINEL | 248 | SNMP_MIB_SENTINEL |
252 | }; | 249 | }; |
253 | 250 | ||
251 | static void icmpmsg_put(struct seq_file *seq) | ||
252 | { | ||
253 | #define PERLINE 16 | ||
254 | |||
255 | int j, i, count; | ||
256 | static int out[PERLINE]; | ||
257 | |||
258 | count = 0; | ||
259 | for (i = 0; i < ICMPMSG_MIB_MAX; i++) { | ||
260 | |||
261 | if (snmp_fold_field((void **) icmpmsg_statistics, i)) | ||
262 | out[count++] = i; | ||
263 | if (count < PERLINE) | ||
264 | continue; | ||
265 | |||
266 | seq_printf(seq, "\nIcmpMsg:"); | ||
267 | for (j = 0; j < PERLINE; ++j) | ||
268 | seq_printf(seq, " %sType%u", i & 0x100 ? "Out" : "In", | ||
269 | i & 0xff); | ||
270 | seq_printf(seq, "\nIcmpMsg: "); | ||
271 | for (j = 0; j < PERLINE; ++j) | ||
272 | seq_printf(seq, " %lu", | ||
273 | snmp_fold_field((void **) icmpmsg_statistics, | ||
274 | out[j])); | ||
275 | seq_putc(seq, '\n'); | ||
276 | } | ||
277 | if (count) { | ||
278 | seq_printf(seq, "\nIcmpMsg:"); | ||
279 | for (j = 0; j < count; ++j) | ||
280 | seq_printf(seq, " %sType%u", out[j] & 0x100 ? "Out" : | ||
281 | "In", out[j] & 0xff); | ||
282 | seq_printf(seq, "\nIcmpMsg:"); | ||
283 | for (j = 0; j < count; ++j) | ||
284 | seq_printf(seq, " %lu", snmp_fold_field((void **) | ||
285 | icmpmsg_statistics, out[j])); | ||
286 | } | ||
287 | |||
288 | #undef PERLINE | ||
289 | } | ||
290 | |||
291 | static void icmp_put(struct seq_file *seq) | ||
292 | { | ||
293 | int i; | ||
294 | |||
295 | seq_puts(seq, "\nIcmp: InMsgs InErrors"); | ||
296 | for (i=0; icmpmibmap[i].name != NULL; i++) | ||
297 | seq_printf(seq, " In%s", icmpmibmap[i].name); | ||
298 | seq_printf(seq, " OutMsgs OutErrors"); | ||
299 | for (i=0; icmpmibmap[i].name != NULL; i++) | ||
300 | seq_printf(seq, " Out%s", icmpmibmap[i].name); | ||
301 | seq_printf(seq, "\nIcmp: %lu %lu", | ||
302 | snmp_fold_field((void **) icmp_statistics, ICMP_MIB_INMSGS), | ||
303 | snmp_fold_field((void **) icmp_statistics, ICMP_MIB_INERRORS)); | ||
304 | for (i=0; icmpmibmap[i].name != NULL; i++) | ||
305 | seq_printf(seq, " %lu", | ||
306 | snmp_fold_field((void **) icmpmsg_statistics, | ||
307 | icmpmibmap[i].index)); | ||
308 | seq_printf(seq, " %lu %lu", | ||
309 | snmp_fold_field((void **) icmp_statistics, ICMP_MIB_OUTMSGS), | ||
310 | snmp_fold_field((void **) icmp_statistics, ICMP_MIB_OUTERRORS)); | ||
311 | for (i=0; icmpmibmap[i].name != NULL; i++) | ||
312 | seq_printf(seq, " %lu", | ||
313 | snmp_fold_field((void **) icmpmsg_statistics, | ||
314 | icmpmibmap[i].index)); | ||
315 | } | ||
316 | |||
254 | /* | 317 | /* |
255 | * Called from the PROCfs module. This outputs /proc/net/snmp. | 318 | * Called from the PROCfs module. This outputs /proc/net/snmp. |
256 | */ | 319 | */ |
@@ -271,15 +334,8 @@ static int snmp_seq_show(struct seq_file *seq, void *v) | |||
271 | snmp_fold_field((void **)ip_statistics, | 334 | snmp_fold_field((void **)ip_statistics, |
272 | snmp4_ipstats_list[i].entry)); | 335 | snmp4_ipstats_list[i].entry)); |
273 | 336 | ||
274 | seq_puts(seq, "\nIcmp:"); | 337 | icmp_put(seq); /* RFC 2011 compatibility */ |
275 | for (i = 0; snmp4_icmp_list[i].name != NULL; i++) | 338 | icmpmsg_put(seq); |
276 | seq_printf(seq, " %s", snmp4_icmp_list[i].name); | ||
277 | |||
278 | seq_puts(seq, "\nIcmp:"); | ||
279 | for (i = 0; snmp4_icmp_list[i].name != NULL; i++) | ||
280 | seq_printf(seq, " %lu", | ||
281 | snmp_fold_field((void **)icmp_statistics, | ||
282 | snmp4_icmp_list[i].entry)); | ||
283 | 339 | ||
284 | seq_puts(seq, "\nTcp:"); | 340 | seq_puts(seq, "\nTcp:"); |
285 | for (i = 0; snmp4_tcp_list[i].name != NULL; i++) | 341 | for (i = 0; snmp4_tcp_list[i].name != NULL; i++) |
@@ -336,6 +392,8 @@ static const struct file_operations snmp_seq_fops = { | |||
336 | .release = single_release, | 392 | .release = single_release, |
337 | }; | 393 | }; |
338 | 394 | ||
395 | |||
396 | |||
339 | /* | 397 | /* |
340 | * Output /proc/net/netstat | 398 | * Output /proc/net/netstat |
341 | */ | 399 | */ |
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 216e01b0f44a..07070c7067f3 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c | |||
@@ -314,6 +314,9 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length, | |||
314 | 314 | ||
315 | iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl); | 315 | iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl); |
316 | } | 316 | } |
317 | if (iph->protocol == IPPROTO_ICMP) | ||
318 | icmp_out_count(((struct icmphdr *) | ||
319 | skb_transport_header(skb))->type); | ||
317 | 320 | ||
318 | err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev, | 321 | err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev, |
319 | dst_output); | 322 | dst_output); |