diff options
-rw-r--r-- | net/core/dev.c | 68 |
1 files changed, 40 insertions, 28 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 99b7bda37d10..39aba4862f21 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -1949,27 +1949,51 @@ static int ing_filter(struct sk_buff *skb) | |||
1949 | struct Qdisc *q; | 1949 | struct Qdisc *q; |
1950 | struct net_device *dev = skb->dev; | 1950 | struct net_device *dev = skb->dev; |
1951 | int result = TC_ACT_OK; | 1951 | int result = TC_ACT_OK; |
1952 | u32 ttl = G_TC_RTTL(skb->tc_verd); | ||
1952 | 1953 | ||
1953 | if (dev->qdisc_ingress) { | 1954 | if (MAX_RED_LOOP < ttl++) { |
1954 | __u32 ttl = (__u32) G_TC_RTTL(skb->tc_verd); | 1955 | printk(KERN_WARNING |
1955 | if (MAX_RED_LOOP < ttl++) { | 1956 | "Redir loop detected Dropping packet (%d->%d)\n", |
1956 | printk(KERN_WARNING "Redir loop detected Dropping packet (%d->%d)\n", | 1957 | skb->iif, dev->ifindex); |
1957 | skb->iif, skb->dev->ifindex); | 1958 | return TC_ACT_SHOT; |
1958 | return TC_ACT_SHOT; | 1959 | } |
1959 | } | ||
1960 | 1960 | ||
1961 | skb->tc_verd = SET_TC_RTTL(skb->tc_verd,ttl); | 1961 | skb->tc_verd = SET_TC_RTTL(skb->tc_verd, ttl); |
1962 | skb->tc_verd = SET_TC_AT(skb->tc_verd, AT_INGRESS); | ||
1962 | 1963 | ||
1963 | skb->tc_verd = SET_TC_AT(skb->tc_verd,AT_INGRESS); | 1964 | spin_lock(&dev->ingress_lock); |
1965 | if ((q = dev->qdisc_ingress) != NULL) | ||
1966 | result = q->enqueue(skb, q); | ||
1967 | spin_unlock(&dev->ingress_lock); | ||
1968 | |||
1969 | return result; | ||
1970 | } | ||
1964 | 1971 | ||
1965 | spin_lock(&dev->ingress_lock); | 1972 | static inline struct sk_buff *handle_ing(struct sk_buff *skb, |
1966 | if ((q = dev->qdisc_ingress) != NULL) | 1973 | struct packet_type **pt_prev, |
1967 | result = q->enqueue(skb, q); | 1974 | int *ret, struct net_device *orig_dev) |
1968 | spin_unlock(&dev->ingress_lock); | 1975 | { |
1976 | if (!skb->dev->qdisc_ingress) | ||
1977 | goto out; | ||
1969 | 1978 | ||
1979 | if (*pt_prev) { | ||
1980 | *ret = deliver_skb(skb, *pt_prev, orig_dev); | ||
1981 | *pt_prev = NULL; | ||
1982 | } else { | ||
1983 | /* Huh? Why does turning on AF_PACKET affect this? */ | ||
1984 | skb->tc_verd = SET_TC_OK2MUNGE(skb->tc_verd); | ||
1970 | } | 1985 | } |
1971 | 1986 | ||
1972 | return result; | 1987 | switch (ing_filter(skb)) { |
1988 | case TC_ACT_SHOT: | ||
1989 | case TC_ACT_STOLEN: | ||
1990 | kfree_skb(skb); | ||
1991 | return NULL; | ||
1992 | } | ||
1993 | |||
1994 | out: | ||
1995 | skb->tc_verd = 0; | ||
1996 | return skb; | ||
1973 | } | 1997 | } |
1974 | #endif | 1998 | #endif |
1975 | 1999 | ||
@@ -2021,21 +2045,9 @@ int netif_receive_skb(struct sk_buff *skb) | |||
2021 | } | 2045 | } |
2022 | 2046 | ||
2023 | #ifdef CONFIG_NET_CLS_ACT | 2047 | #ifdef CONFIG_NET_CLS_ACT |
2024 | if (pt_prev) { | 2048 | skb = handle_ing(skb, &pt_prev, &ret, orig_dev); |
2025 | ret = deliver_skb(skb, pt_prev, orig_dev); | 2049 | if (!skb) |
2026 | pt_prev = NULL; /* noone else should process this after*/ | ||
2027 | } else { | ||
2028 | skb->tc_verd = SET_TC_OK2MUNGE(skb->tc_verd); | ||
2029 | } | ||
2030 | |||
2031 | ret = ing_filter(skb); | ||
2032 | |||
2033 | if (ret == TC_ACT_SHOT || (ret == TC_ACT_STOLEN)) { | ||
2034 | kfree_skb(skb); | ||
2035 | goto out; | 2050 | goto out; |
2036 | } | ||
2037 | |||
2038 | skb->tc_verd = 0; | ||
2039 | ncls: | 2051 | ncls: |
2040 | #endif | 2052 | #endif |
2041 | 2053 | ||