Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d13964f4 authored by Patrick McHardy's avatar Patrick McHardy Committed by David S. Miller
Browse files

[IPV4/6]: Check if packet was actually delivered to a raw socket to decide...


[IPV4/6]: Check if packet was actually delivered to a raw socket to decide whether to send an ICMP unreachable

Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0bd1b59b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -37,6 +37,6 @@ extern struct sock *__raw_v4_lookup(struct sock *sk, unsigned short num,
				    unsigned long raddr, unsigned long laddr,
				    int dif);

extern void raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash);
extern int raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash);

#endif	/* _RAW_H */
+1 −1
Original line number Diff line number Diff line
@@ -7,7 +7,7 @@
extern struct hlist_head raw_v6_htable[RAWV6_HTABLE_SIZE];
extern rwlock_t raw_v6_lock;

extern void ipv6_raw_deliver(struct sk_buff *skb, int nexthdr);
extern int ipv6_raw_deliver(struct sk_buff *skb, int nexthdr);

extern struct sock *__raw_v6_lookup(struct sock *sk, unsigned short num,
				    struct in6_addr *loc_addr, struct in6_addr *rmt_addr,
+2 −2
Original line number Diff line number Diff line
@@ -225,8 +225,8 @@ static inline int ip_local_deliver_finish(struct sk_buff *skb)
		/* If there maybe a raw socket we must check - if not we
		 * don't care less
		 */
		if (raw_sk)
			raw_v4_input(skb, skb->nh.iph, hash);
		if (raw_sk && !raw_v4_input(skb, skb->nh.iph, hash))
			raw_sk = NULL;

		if ((ipprot = rcu_dereference(inet_protos[hash])) != NULL) {
			int ret;
+4 −1
Original line number Diff line number Diff line
@@ -150,10 +150,11 @@ static __inline__ int icmp_filter(struct sock *sk, struct sk_buff *skb)
 * RFC 1122: SHOULD pass TOS value up to the transport layer.
 * -> It does. And not only TOS, but all IP header.
 */
void raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash)
int raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash)
{
	struct sock *sk;
	struct hlist_head *head;
	int delivered = 0;

	read_lock(&raw_v4_lock);
	head = &raw_v4_htable[hash];
@@ -164,6 +165,7 @@ void raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash)
			     skb->dev->ifindex);

	while (sk) {
		delivered = 1;
		if (iph->protocol != IPPROTO_ICMP || !icmp_filter(sk, skb)) {
			struct sk_buff *clone = skb_clone(skb, GFP_ATOMIC);

@@ -177,6 +179,7 @@ void raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash)
	}
out:
	read_unlock(&raw_v4_lock);
	return delivered;
}

void raw_err (struct sock *sk, struct sk_buff *skb, u32 info)
+2 −2
Original line number Diff line number Diff line
@@ -166,8 +166,8 @@ static inline int ip6_input_finish(struct sk_buff *skb)
	nexthdr = skb->nh.raw[nhoff];

	raw_sk = sk_head(&raw_v6_htable[nexthdr & (MAX_INET_PROTOS - 1)]);
	if (raw_sk)
		ipv6_raw_deliver(skb, nexthdr);
	if (raw_sk && !ipv6_raw_deliver(skb, nexthdr))
		raw_sk = NULL;

	hash = nexthdr & (MAX_INET_PROTOS - 1);
	if ((ipprot = rcu_dereference(inet6_protos[hash])) != NULL) {
Loading