*
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/jiffies.h>
struct {
struct icmphdr icmph;
- __u32 times[3];
+ __be32 times[3];
} data;
int head_len;
struct ip_options replyopts;
};
/* Control parameters for ECHO replies. */
-int sysctl_icmp_echo_ignore_all;
-int sysctl_icmp_echo_ignore_broadcasts = 1;
+int sysctl_icmp_echo_ignore_all __read_mostly;
+int sysctl_icmp_echo_ignore_broadcasts __read_mostly = 1;
/* Control parameter - ignore bogus broadcast responses? */
-int sysctl_icmp_ignore_bogus_error_responses = 1;
+int sysctl_icmp_ignore_bogus_error_responses __read_mostly = 1;
/*
* Configurable global rate limit.
* time exceeded (11), parameter problem (12)
*/
-int sysctl_icmp_ratelimit = 1 * HZ;
-int sysctl_icmp_ratemask = 0x1818;
-int sysctl_icmp_errors_use_inbound_ifaddr;
+int sysctl_icmp_ratelimit __read_mostly = 1 * HZ;
+int sysctl_icmp_ratemask __read_mostly = 0x1818;
+int sysctl_icmp_errors_use_inbound_ifaddr __read_mostly;
/*
* ICMP control array. This specifies what to do with each ICMP.
struct sk_buff *skb)
{
struct icmp_bxm *icmp_param = (struct icmp_bxm *)from;
- unsigned int csum;
+ __wsum csum;
csum = skb_copy_and_csum_bits(icmp_param->skb,
icmp_param->offset + offset,
ip_flush_pending_frames(icmp_socket->sk);
else if ((skb = skb_peek(&icmp_socket->sk->sk_write_queue)) != NULL) {
struct icmphdr *icmph = skb->h.icmph;
- unsigned int csum = 0;
+ __wsum csum = 0;
struct sk_buff *skb1;
skb_queue_walk(&icmp_socket->sk->sk_write_queue, skb1) {
struct inet_sock *inet = inet_sk(sk);
struct ipcm_cookie ipc;
struct rtable *rt = (struct rtable *)skb->dst;
- u32 daddr;
+ __be32 daddr;
if (ip_options_echo(&icmp_param->replyopts, skb))
return;
.saddr = rt->rt_spec_dst,
.tos = RT_TOS(skb->nh.iph->tos) } },
.proto = IPPROTO_ICMP };
+ security_skb_classify_flow(skb, &fl);
if (ip_route_output_key(&rt, &fl))
goto out_unlock;
}
* MUST reply to only the first fragment.
*/
-void icmp_send(struct sk_buff *skb_in, int type, int code, u32 info)
+void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
{
struct iphdr *iph;
int room;
struct icmp_bxm icmp_param;
struct rtable *rt = (struct rtable *)skb_in->dst;
struct ipcm_cookie ipc;
- u32 saddr;
+ __be32 saddr;
u8 tos;
if (!rt)
}
}
};
+ security_skb_classify_flow(skb_in, &fl);
if (ip_route_output_key(&rt, &fl))
goto out_unlock;
}
static void icmp_redirect(struct sk_buff *skb)
{
struct iphdr *iph;
- unsigned long ip;
if (skb->len < sizeof(struct iphdr))
goto out_err;
goto out;
iph = (struct iphdr *)skb->data;
- ip = iph->daddr;
switch (skb->h.icmph->code & 7) {
case ICMP_REDIR_NET:
*/
case ICMP_REDIR_HOST:
case ICMP_REDIR_HOSTTOS:
- ip_rt_redirect(skb->nh.iph->saddr, ip, skb->h.icmph->un.gateway,
- iph->saddr, iph->tos, skb->dev);
+ ip_rt_redirect(skb->nh.iph->saddr, iph->daddr,
+ skb->h.icmph->un.gateway,
+ iph->saddr, skb->dev);
break;
}
out:
if (in_dev->ifa_list &&
IN_DEV_LOG_MARTIANS(in_dev) &&
IN_DEV_FORWARD(in_dev)) {
- u32 _mask, *mp;
+ __be32 _mask, *mp;
mp = skb_header_pointer(skb, 0, sizeof(_mask), &_mask);
BUG_ON(mp == NULL);
ICMP_INC_STATS_BH(ICMP_MIB_INMSGS);
switch (skb->ip_summed) {
- case CHECKSUM_HW:
- if (!(u16)csum_fold(skb->csum))
+ case CHECKSUM_COMPLETE:
+ if (!csum_fold(skb->csum))
break;
/* fall through */
case CHECKSUM_NONE:
}
}
-#if defined(CONFIG_VNET) || defined(CONFIG_VNET_MODULE)
- /* VNET: Bypass stack if the echo ID was bound to a (presumably raw) socket */
- if (vnet_active && skb->sk) {
- switch (icmph->type) {
- case ICMP_ECHOREPLY:
- case ICMP_ECHO:
- case ICMP_TIMESTAMP:
- case ICMP_TIMESTAMPREPLY:
- case ICMP_INFO_REQUEST:
- case ICMP_INFO_REPLY:
- case ICMP_ADDRESS:
- case ICMP_ADDRESSREPLY:
- goto drop;
- }
- }
-#endif
-
ICMP_INC_STATS_BH(icmp_pointers[icmph->type].input_entry);
icmp_pointers[icmph->type].handler(skb);
struct inet_sock *inet;
int i;
- for_each_cpu(i) {
+ for_each_possible_cpu(i) {
int err;
err = sock_create_kern(PF_INET, SOCK_RAW, IPPROTO_ICMP,