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); |
