diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/netfilter_ipv4.h | 3 | ||||
-rw-r--r-- | include/linux/tc_act/tc_defact.h | 21 | ||||
-rw-r--r-- | include/net/act_generic.h | 142 | ||||
-rw-r--r-- | include/net/ax25.h | 8 | ||||
-rw-r--r-- | include/net/ipv6.h | 2 | ||||
-rw-r--r-- | include/net/tc_act/tc_defact.h | 13 | ||||
-rw-r--r-- | include/net/tcp.h | 11 |
7 files changed, 194 insertions, 6 deletions
diff --git a/include/linux/netfilter_ipv4.h b/include/linux/netfilter_ipv4.h index c9bacf9b2431..9e5750079e09 100644 --- a/include/linux/netfilter_ipv4.h +++ b/include/linux/netfilter_ipv4.h @@ -62,6 +62,9 @@ enum nf_ip_hook_priorities { NF_IP_PRI_FILTER = 0, NF_IP_PRI_NAT_SRC = 100, NF_IP_PRI_SELINUX_LAST = 225, + NF_IP_PRI_CONNTRACK_HELPER = INT_MAX - 2, + NF_IP_PRI_NAT_SEQ_ADJUST = INT_MAX - 1, + NF_IP_PRI_CONNTRACK_CONFIRM = INT_MAX, NF_IP_PRI_LAST = INT_MAX, }; diff --git a/include/linux/tc_act/tc_defact.h b/include/linux/tc_act/tc_defact.h new file mode 100644 index 000000000000..964f473af0f0 --- /dev/null +++ b/include/linux/tc_act/tc_defact.h @@ -0,0 +1,21 @@ +#ifndef __LINUX_TC_DEF_H +#define __LINUX_TC_DEF_H + +#include <linux/pkt_cls.h> + +struct tc_defact +{ + tc_gen; +}; + +enum +{ + TCA_DEF_UNSPEC, + TCA_DEF_TM, + TCA_DEF_PARMS, + TCA_DEF_DATA, + __TCA_DEF_MAX +}; +#define TCA_DEF_MAX (__TCA_DEF_MAX - 1) + +#endif diff --git a/include/net/act_generic.h b/include/net/act_generic.h new file mode 100644 index 000000000000..95b120781c14 --- /dev/null +++ b/include/net/act_generic.h @@ -0,0 +1,142 @@ +/* + * include/net/act_generic.h + * +*/ +#ifndef ACT_GENERIC_H +#define ACT_GENERIC_H +static inline int tcf_defact_release(struct tcf_defact *p, int bind) +{ + int ret = 0; + if (p) { + if (bind) { + p->bindcnt--; + } + p->refcnt--; + if (p->bindcnt <= 0 && p->refcnt <= 0) { + kfree(p->defdata); + tcf_hash_destroy(p); + ret = 1; + } + } + return ret; +} + +static inline int +alloc_defdata(struct tcf_defact *p, u32 datalen, void *defdata) +{ + p->defdata = kmalloc(datalen, GFP_KERNEL); + if (p->defdata == NULL) + return -ENOMEM; + p->datalen = datalen; + memcpy(p->defdata, defdata, datalen); + return 0; +} + +static inline int +realloc_defdata(struct tcf_defact *p, u32 datalen, void *defdata) +{ + /* safer to be just brute force for now */ + kfree(p->defdata); + return alloc_defdata(p, datalen, defdata); +} + +static inline int +tcf_defact_init(struct rtattr *rta, struct rtattr *est, + struct tc_action *a, int ovr, int bind) +{ + struct rtattr *tb[TCA_DEF_MAX]; + struct tc_defact *parm; + struct tcf_defact *p; + void *defdata; + u32 datalen = 0; + int ret = 0; + + if (rta == NULL || rtattr_parse_nested(tb, TCA_DEF_MAX, rta) < 0) + return -EINVAL; + + if (tb[TCA_DEF_PARMS - 1] == NULL || + RTA_PAYLOAD(tb[TCA_DEF_PARMS - 1]) < sizeof(*parm)) + return -EINVAL; + + parm = RTA_DATA(tb[TCA_DEF_PARMS - 1]); + defdata = RTA_DATA(tb[TCA_DEF_DATA - 1]); + if (defdata == NULL) + return -EINVAL; + + datalen = RTA_PAYLOAD(tb[TCA_DEF_DATA - 1]); + if (datalen <= 0) + return -EINVAL; + + p = tcf_hash_check(parm->index, a, ovr, bind); + if (p == NULL) { + p = tcf_hash_create(parm->index, est, a, sizeof(*p), ovr, bind); + if (p == NULL) + return -ENOMEM; + + ret = alloc_defdata(p, datalen, defdata); + if (ret < 0) { + kfree(p); + return ret; + } + ret = ACT_P_CREATED; + } else { + if (!ovr) { + tcf_defact_release(p, bind); + return -EEXIST; + } + realloc_defdata(p, datalen, defdata); + } + + spin_lock_bh(&p->lock); + p->action = parm->action; + spin_unlock_bh(&p->lock); + if (ret == ACT_P_CREATED) + tcf_hash_insert(p); + return ret; +} + +static inline int tcf_defact_cleanup(struct tc_action *a, int bind) +{ + struct tcf_defact *p = PRIV(a, defact); + + if (p != NULL) + return tcf_defact_release(p, bind); + return 0; +} + +static inline int +tcf_defact_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref) +{ + unsigned char *b = skb->tail; + struct tc_defact opt; + struct tcf_defact *p = PRIV(a, defact); + struct tcf_t t; + + opt.index = p->index; + opt.refcnt = p->refcnt - ref; + opt.bindcnt = p->bindcnt - bind; + opt.action = p->action; + RTA_PUT(skb, TCA_DEF_PARMS, sizeof(opt), &opt); + RTA_PUT(skb, TCA_DEF_DATA, p->datalen, p->defdata); + t.install = jiffies_to_clock_t(jiffies - p->tm.install); + t.lastuse = jiffies_to_clock_t(jiffies - p->tm.lastuse); + t.expires = jiffies_to_clock_t(p->tm.expires); + RTA_PUT(skb, TCA_DEF_TM, sizeof(t), &t); + return skb->len; + +rtattr_failure: + skb_trim(skb, b - skb->data); + return -1; +} + +#define tca_use_default_ops \ + .dump = tcf_defact_dump, \ + .cleanup = tcf_defact_cleanup, \ + .init = tcf_defact_init, \ + .walk = tcf_generic_walker, \ + +#define tca_use_default_defines(name) \ + static u32 idx_gen; \ + static struct tcf_defact *tcf_##name_ht[MY_TAB_SIZE]; \ + static DEFINE_RWLOCK(##name_lock); +#endif /* _NET_ACT_GENERIC_H */ diff --git a/include/net/ax25.h b/include/net/ax25.h index 875edbba396d..9e6368a54547 100644 --- a/include/net/ax25.h +++ b/include/net/ax25.h @@ -220,6 +220,14 @@ static __inline__ void ax25_cb_put(ax25_cb *ax25) } } +static inline unsigned short ax25_type_trans(struct sk_buff *skb, struct net_device *dev) +{ + skb->dev = dev; + skb->pkt_type = PACKET_HOST; + skb->mac.raw = skb->data; + return htons(ETH_P_AX25); +} + /* af_ax25.c */ extern struct hlist_head ax25_list; extern spinlock_t ax25_list_lock; diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 87c45cbfbaf6..771b47e30f86 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -416,7 +416,7 @@ extern void ipv6_push_frag_opts(struct sk_buff *skb, u8 *proto); extern int ipv6_skip_exthdr(const struct sk_buff *, int start, - u8 *nexthdrp, int len); + u8 *nexthdrp); extern int ipv6_ext_hdr(u8 nexthdr); diff --git a/include/net/tc_act/tc_defact.h b/include/net/tc_act/tc_defact.h new file mode 100644 index 000000000000..463aa671f95d --- /dev/null +++ b/include/net/tc_act/tc_defact.h @@ -0,0 +1,13 @@ +#ifndef __NET_TC_DEF_H +#define __NET_TC_DEF_H + +#include <net/act_api.h> + +struct tcf_defact +{ + tca_gen(defact); + u32 datalen; + void *defdata; +}; + +#endif diff --git a/include/net/tcp.h b/include/net/tcp.h index 503810a70e21..9355ae5b1d75 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -1417,19 +1417,20 @@ tcp_nagle_check(const struct tcp_sock *tp, const struct sk_buff *skb, tcp_minshall_check(tp)))); } -extern void tcp_set_skb_tso_segs(struct sk_buff *, unsigned int); +extern void tcp_set_skb_tso_segs(struct sock *, struct sk_buff *); /* This checks if the data bearing packet SKB (usually sk->sk_send_head) * should be put on the wire right now. */ -static __inline__ int tcp_snd_test(const struct tcp_sock *tp, +static __inline__ int tcp_snd_test(struct sock *sk, struct sk_buff *skb, unsigned cur_mss, int nonagle) { + struct tcp_sock *tp = tcp_sk(sk); int pkts = tcp_skb_pcount(skb); if (!pkts) { - tcp_set_skb_tso_segs(skb, tp->mss_cache_std); + tcp_set_skb_tso_segs(sk, skb); pkts = tcp_skb_pcount(skb); } @@ -1490,7 +1491,7 @@ static __inline__ void __tcp_push_pending_frames(struct sock *sk, if (skb) { if (!tcp_skb_is_last(sk, skb)) nonagle = TCP_NAGLE_PUSH; - if (!tcp_snd_test(tp, skb, cur_mss, nonagle) || + if (!tcp_snd_test(sk, skb, cur_mss, nonagle) || tcp_write_xmit(sk, nonagle)) tcp_check_probe_timer(sk, tp); } @@ -1508,7 +1509,7 @@ static __inline__ int tcp_may_send_now(struct sock *sk, struct tcp_sock *tp) struct sk_buff *skb = sk->sk_send_head; return (skb && - tcp_snd_test(tp, skb, tcp_current_mss(sk, 1), + tcp_snd_test(sk, skb, tcp_current_mss(sk, 1), tcp_skb_is_last(sk, skb) ? TCP_NAGLE_PUSH : tp->nonagle)); } |