diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/bluetooth/hidp/core.c | 49 | ||||
-rw-r--r-- | net/bluetooth/rfcomm/tty.c | 3 | ||||
-rw-r--r-- | net/core/rtnetlink.c | 44 | ||||
-rw-r--r-- | net/ipv4/cipso_ipv4.c | 4 | ||||
-rw-r--r-- | net/ipv4/fib_trie.c | 3 | ||||
-rw-r--r-- | net/ipv4/icmp.c | 3 | ||||
-rw-r--r-- | net/ipv4/inet_hashtables.c | 6 | ||||
-rw-r--r-- | net/ipv4/xfrm4_mode_beet.c | 2 | ||||
-rw-r--r-- | net/ipv6/icmp.c | 3 | ||||
-rw-r--r-- | net/ipv6/inet6_hashtables.c | 2 | ||||
-rw-r--r-- | net/netlabel/netlabel_cipso_v4.c | 2 | ||||
-rw-r--r-- | net/netlabel/netlabel_cipso_v4.h | 3 | ||||
-rw-r--r-- | net/netlabel/netlabel_domainhash.h | 1 | ||||
-rw-r--r-- | net/netlabel/netlabel_kapi.c | 177 | ||||
-rw-r--r-- | net/sched/cls_flow.c | 21 | ||||
-rw-r--r-- | net/sched/em_meta.c | 17 | ||||
-rw-r--r-- | net/sctp/auth.c | 6 | ||||
-rw-r--r-- | net/sctp/sm_statefuns.c | 4 |
18 files changed, 257 insertions, 93 deletions
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 782a226..519cdb9 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -135,8 +135,8 @@ static void __hidp_copy_session(struct hidp_session *session, struct hidp_connin } } -static inline int hidp_queue_event(struct hidp_session *session, struct input_dev *dev, - unsigned int type, unsigned int code, int value) +static int hidp_queue_event(struct hidp_session *session, struct input_dev *dev, + unsigned int type, unsigned int code, int value) { unsigned char newleds; struct sk_buff *skb; @@ -243,7 +243,8 @@ static void hidp_input_report(struct hidp_session *session, struct sk_buff *skb) input_sync(dev); } -static inline int hidp_queue_report(struct hidp_session *session, unsigned char *data, int size) +static int hidp_queue_report(struct hidp_session *session, + unsigned char *data, int size) { struct sk_buff *skb; @@ -287,7 +288,7 @@ static void hidp_idle_timeout(unsigned long arg) hidp_schedule(session); } -static inline void hidp_set_timer(struct hidp_session *session) +static void hidp_set_timer(struct hidp_session *session) { if (session->idle_to > 0) mod_timer(&session->timer, jiffies + HZ * session->idle_to); @@ -332,7 +333,8 @@ static inline int hidp_send_ctrl_message(struct hidp_session *session, return err; } -static inline void hidp_process_handshake(struct hidp_session *session, unsigned char param) +static void hidp_process_handshake(struct hidp_session *session, + unsigned char param) { BT_DBG("session %p param 0x%02x", session, param); @@ -365,38 +367,23 @@ static inline void hidp_process_handshake(struct hidp_session *session, unsigned } } -static inline void hidp_process_hid_control(struct hidp_session *session, unsigned char param) +static void hidp_process_hid_control(struct hidp_session *session, + unsigned char param) { BT_DBG("session %p param 0x%02x", session, param); - switch (param) { - case HIDP_CTRL_NOP: - break; - - case HIDP_CTRL_VIRTUAL_CABLE_UNPLUG: + if (param == HIDP_CTRL_VIRTUAL_CABLE_UNPLUG) { /* Flush the transmit queues */ skb_queue_purge(&session->ctrl_transmit); skb_queue_purge(&session->intr_transmit); /* Kill session thread */ atomic_inc(&session->terminate); - break; - - case HIDP_CTRL_HARD_RESET: - case HIDP_CTRL_SOFT_RESET: - case HIDP_CTRL_SUSPEND: - case HIDP_CTRL_EXIT_SUSPEND: - /* FIXME: We have to parse these and return no error */ - break; - - default: - __hidp_send_ctrl_message(session, - HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0); - break; } } -static inline void hidp_process_data(struct hidp_session *session, struct sk_buff *skb, unsigned char param) +static void hidp_process_data(struct hidp_session *session, struct sk_buff *skb, + unsigned char param) { BT_DBG("session %p skb %p len %d param 0x%02x", session, skb, skb->len, param); @@ -423,7 +410,8 @@ static inline void hidp_process_data(struct hidp_session *session, struct sk_buf } } -static inline void hidp_recv_ctrl_frame(struct hidp_session *session, struct sk_buff *skb) +static void hidp_recv_ctrl_frame(struct hidp_session *session, + struct sk_buff *skb) { unsigned char hdr, type, param; @@ -457,7 +445,8 @@ static inline void hidp_recv_ctrl_frame(struct hidp_session *session, struct sk_ kfree_skb(skb); } -static inline void hidp_recv_intr_frame(struct hidp_session *session, struct sk_buff *skb) +static void hidp_recv_intr_frame(struct hidp_session *session, + struct sk_buff *skb) { unsigned char hdr; @@ -625,7 +614,8 @@ static struct device *hidp_get_device(struct hidp_session *session) return conn ? &conn->dev : NULL; } -static inline int hidp_setup_input(struct hidp_session *session, struct hidp_connadd_req *req) +static int hidp_setup_input(struct hidp_session *session, + struct hidp_connadd_req *req) { struct input_dev *input = session->input; int i; @@ -702,7 +692,8 @@ static void hidp_setup_quirks(struct hid_device *hid) hid->quirks = hidp_blacklist[n].quirks; } -static inline void hidp_setup_hid(struct hidp_session *session, struct hidp_connadd_req *req) +static void hidp_setup_hid(struct hidp_session *session, + struct hidp_connadd_req *req) { struct hid_device *hid = session->hid; struct hid_report *report; diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index 788c703..e4c779b 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c @@ -429,7 +429,8 @@ static int rfcomm_release_dev(void __user *arg) if (dev->tty) tty_vhangup(dev->tty); - rfcomm_dev_del(dev); + if (!test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) + rfcomm_dev_del(dev); rfcomm_dev_put(dev); return 0; } diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index ddbdde8..61ac8d0 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -82,32 +82,6 @@ int rtnl_trylock(void) return mutex_trylock(&rtnl_mutex); } -int rtattr_parse(struct rtattr *tb[], int maxattr, struct rtattr *rta, int len) -{ - memset(tb, 0, sizeof(struct rtattr*)*maxattr); - - while (RTA_OK(rta, len)) { - unsigned flavor = rta->rta_type; - if (flavor && flavor <= maxattr) - tb[flavor-1] = rta; - rta = RTA_NEXT(rta, len); - } - return 0; -} - -int __rtattr_parse_nested_compat(struct rtattr *tb[], int maxattr, - struct rtattr *rta, int len) -{ - if (RTA_PAYLOAD(rta) < len) - return -1; - if (RTA_PAYLOAD(rta) >= RTA_ALIGN(len) + sizeof(struct rtattr)) { - rta = RTA_DATA(rta) + RTA_ALIGN(len); - return rtattr_parse_nested(tb, maxattr, rta); - } - memset(tb, 0, sizeof(struct rtattr *) * maxattr); - return 0; -} - static struct rtnl_link *rtnl_msg_handlers[NPROTO]; static inline int rtm_msgindex(int msgtype) @@ -442,21 +416,6 @@ void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const void *data memset(RTA_DATA(rta) + attrlen, 0, RTA_ALIGN(size) - size); } -size_t rtattr_strlcpy(char *dest, const struct rtattr *rta, size_t size) -{ - size_t ret = RTA_PAYLOAD(rta); - char *src = RTA_DATA(rta); - - if (ret > 0 && src[ret - 1] == '\0') - ret--; - if (size > 0) { - size_t len = (ret >= size) ? size - 1 : ret; - memset(dest, 0, size); - memcpy(dest, src, len); - } - return ret; -} - int rtnetlink_send(struct sk_buff *skb, struct net *net, u32 pid, unsigned group, int echo) { struct sock *rtnl = net->rtnl; @@ -1411,9 +1370,6 @@ void __init rtnetlink_init(void) } EXPORT_SYMBOL(__rta_fill); -EXPORT_SYMBOL(rtattr_strlcpy); -EXPORT_SYMBOL(rtattr_parse); -EXPORT_SYMBOL(__rtattr_parse_nested_compat); EXPORT_SYMBOL(rtnetlink_put_metrics); EXPORT_SYMBOL(rtnl_lock); EXPORT_SYMBOL(rtnl_trylock); diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c index a224106..8cd357f 100644 --- a/net/ipv4/cipso_ipv4.c +++ b/net/ipv4/cipso_ipv4.c @@ -547,8 +547,8 @@ int cipso_v4_doi_remove(u32 doi, rcu_read_lock(); list_for_each_entry_rcu(dom_iter, &doi_def->dom_list, list) if (dom_iter->valid) - netlbl_domhsh_remove(dom_iter->domain, - audit_info); + netlbl_cfg_map_del(dom_iter->domain, + audit_info); rcu_read_unlock(); cipso_v4_cache_invalidate(); call_rcu(&doi_def->rcu, callback); diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 35851c9..f5fba3f 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -2431,8 +2431,7 @@ static int fib_trie_seq_show(struct seq_file *seq, void *v) rtn_type(buf2, sizeof(buf2), fa->fa_type)); if (fa->fa_tos) - seq_printf(seq, "tos =%d\n", - fa->fa_tos); + seq_printf(seq, " tos=%d", fa->fa_tos); seq_putc(seq, '\n'); } } diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index a7321a8..a13c074 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -1015,7 +1015,8 @@ int icmp_rcv(struct sk_buff *skb) goto error; } - __skb_pull(skb, sizeof(*icmph)); + if (!pskb_pull(skb, sizeof(*icmph))) + goto error; icmph = icmp_hdr(skb); diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c index 90f422c..9cac6c0 100644 --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c @@ -398,7 +398,7 @@ out: EXPORT_SYMBOL_GPL(inet_unhash); int __inet_hash_connect(struct inet_timewait_death_row *death_row, - struct sock *sk, + struct sock *sk, u32 port_offset, int (*check_established)(struct inet_timewait_death_row *, struct sock *, __u16, struct inet_timewait_sock **), void (*hash)(struct sock *sk)) @@ -413,7 +413,7 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row, if (!snum) { int i, remaining, low, high, port; static u32 hint; - u32 offset = hint + inet_sk_port_offset(sk); + u32 offset = hint + port_offset; struct hlist_node *node; struct inet_timewait_sock *tw = NULL; @@ -502,7 +502,7 @@ EXPORT_SYMBOL_GPL(__inet_hash_connect); int inet_hash_connect(struct inet_timewait_death_row *death_row, struct sock *sk) { - return __inet_hash_connect(death_row, sk, + return __inet_hash_connect(death_row, sk, inet_sk_port_offset(sk), __inet_check_established, __inet_hash_nolisten); } diff --git a/net/ipv4/xfrm4_mode_beet.c b/net/ipv4/xfrm4_mode_beet.c index e093a7b..b47030b 100644 --- a/net/ipv4/xfrm4_mode_beet.c +++ b/net/ipv4/xfrm4_mode_beet.c @@ -102,7 +102,7 @@ static int xfrm4_beet_input(struct xfrm_state *x, struct sk_buff *skb) XFRM_MODE_SKB_CB(skb)->protocol = ph->nexthdr; - if (!pskb_may_pull(skb, phlen)); + if (!pskb_may_pull(skb, phlen)) goto out; __skb_pull(skb, phlen); } diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index cbb5b9c..121d517 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -683,7 +683,8 @@ static int icmpv6_rcv(struct sk_buff *skb) } } - __skb_pull(skb, sizeof(*hdr)); + if (!pskb_pull(skb, sizeof(*hdr))) + goto discard_it; hdr = icmp6_hdr(skb); diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c index 43f3993..99fd25f 100644 --- a/net/ipv6/inet6_hashtables.c +++ b/net/ipv6/inet6_hashtables.c @@ -236,7 +236,7 @@ static inline u32 inet6_sk_port_offset(const struct sock *sk) int inet6_hash_connect(struct inet_timewait_death_row *death_row, struct sock *sk) { - return __inet_hash_connect(death_row, sk, + return __inet_hash_connect(death_row, sk, inet6_sk_port_offset(sk), __inet6_check_established, __inet6_hash); } diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c index becf91a..c7ad64d 100644 --- a/net/netlabel/netlabel_cipso_v4.c +++ b/net/netlabel/netlabel_cipso_v4.c @@ -90,7 +90,7 @@ static const struct nla_policy netlbl_cipsov4_genl_policy[NLBL_CIPSOV4_A_MAX + 1 * safely. * */ -static void netlbl_cipsov4_doi_free(struct rcu_head *entry) +void netlbl_cipsov4_doi_free(struct rcu_head *entry) { struct cipso_v4_doi *ptr; diff --git a/net/netlabel/netlabel_cipso_v4.h b/net/netlabel/netlabel_cipso_v4.h index f03cf9b..220cb9d 100644 --- a/net/netlabel/netlabel_cipso_v4.h +++ b/net/netlabel/netlabel_cipso_v4.h @@ -163,4 +163,7 @@ enum { /* NetLabel protocol functions */ int netlbl_cipsov4_genl_init(void); +/* Free the memory associated with a CIPSOv4 DOI definition */ +void netlbl_cipsov4_doi_free(struct rcu_head *entry); + #endif diff --git a/net/netlabel/netlabel_domainhash.h b/net/netlabel/netlabel_domainhash.h index 3689956..8220990 100644 --- a/net/netlabel/netlabel_domainhash.h +++ b/net/netlabel/netlabel_domainhash.h @@ -61,6 +61,7 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry, struct netlbl_audit *audit_info); int netlbl_domhsh_add_default(struct netlbl_dom_map *entry, struct netlbl_audit *audit_info); +int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info); int netlbl_domhsh_remove_default(struct netlbl_audit *audit_info); struct netlbl_dom_map *netlbl_domhsh_getentry(const char *domain); int netlbl_domhsh_walk(u32 *skip_bkt, diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c index c69e3e1..39793a1 100644 --- a/net/netlabel/netlabel_kapi.c +++ b/net/netlabel/netlabel_kapi.c @@ -30,6 +30,7 @@ #include <linux/init.h> #include <linux/types.h> +#include <linux/audit.h> #include <net/ip.h> #include <net/netlabel.h> #include <net/cipso_ipv4.h> @@ -38,10 +39,186 @@ #include "netlabel_domainhash.h" #include "netlabel_unlabeled.h" +#include "netlabel_cipso_v4.h" #include "netlabel_user.h" #include "netlabel_mgmt.h" /* + * Configuration Functions + */ + +/** + * netlbl_cfg_map_del - Remove a NetLabel/LSM domain mapping + * @domain: the domain mapping to remove + * @audit_info: NetLabel audit information + * + * Description: + * Removes a NetLabel/LSM domain mapping. A @domain value of NULL causes the + * default domain mapping to be removed. Returns zero on success, negative + * values on failure. + * + */ +int netlbl_cfg_map_del(const char *domain, struct netlbl_audit *audit_info) +{ + return netlbl_domhsh_remove(domain, audit_info); +} + +/** + * netlbl_cfg_unlbl_add_map - Add an unlabeled NetLabel/LSM domain mapping + * @domain: the domain mapping to add + * @audit_info: NetLabel audit information + * + * Description: + * Adds a new unlabeled NetLabel/LSM domain mapping. A @domain value of NULL + * causes a new default domain mapping to be added. Returns zero on success, + * negative values on failure. + * + */ +int netlbl_cfg_unlbl_add_map(const char *domain, + struct netlbl_audit *audit_info) +{ + int ret_val = -ENOMEM; + struct netlbl_dom_map *entry; + + entry = kzalloc(sizeof(*entry), GFP_ATOMIC); + if (entry == NULL) + goto cfg_unlbl_add_map_failure; + if (domain != NULL) { + entry->domain = kstrdup(domain, GFP_ATOMIC); + if (entry->domain == NULL) + goto cfg_unlbl_add_map_failure; + } + entry->type = NETLBL_NLTYPE_UNLABELED; + + ret_val = netlbl_domhsh_add(entry, audit_info); + if (ret_val != 0) + goto cfg_unlbl_add_map_failure; + + return 0; + +cfg_unlbl_add_map_failure: + if (entry != NULL) + kfree(entry->domain); + kfree(entry); + return ret_val; +} + +/** + * netlbl_cfg_cipsov4_add - Add a new CIPSOv4 DOI definition + * @doi_def: the DOI definition + * @audit_info: NetLabel audit information + * + * Description: + * Add a new CIPSOv4 DOI definition to the NetLabel subsystem. Returns zero on + * success, negative values on failure. + * + */ +int netlbl_cfg_cipsov4_add(struct cipso_v4_doi *doi_def, + struct netlbl_audit *audit_info) +{ + int ret_val; + const char *type_str; + struct audit_buffer *audit_buf; + + ret_val = cipso_v4_doi_add(doi_def); + + audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_ADD, + audit_info); + if (audit_buf != NULL) { + switch (doi_def->type) { + case CIPSO_V4_MAP_STD: + type_str = "std"; + break; + case CIPSO_V4_MAP_PASS: + type_str = "pass"; + break; + default: + type_str = "(unknown)"; + } + audit_log_format(audit_buf, + " cipso_doi=%u cipso_type=%s res=%u", + doi_def->doi, + type_str, + ret_val == 0 ? 1 : 0); + audit_log_end(audit_buf); + } + + return ret_val; +} + +/** + * netlbl_cfg_cipsov4_add_map - Add a new CIPSOv4 DOI definition and mapping + * @doi_def: the DOI definition + * @domain: the domain mapping to add + * @audit_info: NetLabel audit information + * + * Description: + * Add a new CIPSOv4 DOI definition and NetLabel/LSM domain mapping for this + * new DOI definition to the NetLabel subsystem. A @domain value of NULL adds + * a new default domain mapping. Returns zero on success, negative values on + * failure. + * + */ +int netlbl_cfg_cipsov4_add_map(struct cipso_v4_doi *doi_def, + const char *domain, + struct netlbl_audit *audit_info) +{ + int ret_val = -ENOMEM; + struct netlbl_dom_map *entry; + + entry = kzalloc(sizeof(*entry), GFP_ATOMIC); + if (entry == NULL) + goto cfg_cipsov4_add_map_failure; + if (domain != NULL) { + entry->domain = kstrdup(domain, GFP_ATOMIC); + if (entry->domain == NULL) + goto cfg_cipsov4_add_map_failure; + } + entry->type = NETLBL_NLTYPE_CIPSOV4; + entry->type_def.cipsov4 = doi_def; + + /* Grab a RCU read lock here so nothing happens to the doi_def variable + * between adding it to the CIPSOv4 protocol engine and adding a + * domain mapping for it. */ + + rcu_read_lock(); + ret_val = netlbl_cfg_cipsov4_add(doi_def, audit_info); + if (ret_val != 0) + goto cfg_cipsov4_add_map_failure_unlock; + ret_val = netlbl_domhsh_add(entry, audit_info); + if (ret_val != 0) + goto cfg_cipsov4_add_map_failure_remove_doi; + rcu_read_unlock(); + + return 0; + +cfg_cipsov4_add_map_failure_remove_doi: + cipso_v4_doi_remove(doi_def->doi, audit_info, netlbl_cipsov4_doi_free); +cfg_cipsov4_add_map_failure_unlock: + rcu_read_unlock(); +cfg_cipsov4_add_map_failure: + if (entry != NULL) + kfree(entry->domain); + kfree(entry); + return ret_val; +} + +/** + * netlbl_cfg_cipsov4_del - Removean existing CIPSOv4 DOI definition + * @doi: the CIPSO DOI value + * @audit_info: NetLabel audit information + * + * Description: + * Removes an existing CIPSOv4 DOI definition from the NetLabel subsystem. + * Returns zero on success, negative values on failure. + * + */ +int netlbl_cfg_cipsov4_del(u32 doi, struct netlbl_audit *audit_info) +{ + return cipso_v4_doi_remove(doi, audit_info, netlbl_cipsov4_doi_free); +} + +/* * Security Attribute Functions */ diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c index 5a7f6a3..971b867 100644 --- a/net/sched/cls_flow.c +++ b/net/sched/cls_flow.c @@ -19,6 +19,7 @@ #include <linux/in.h> #include <linux/ip.h> #include <linux/ipv6.h> +#include <linux/if_vlan.h> #include <net/pkt_cls.h> #include <net/ip.h> @@ -270,6 +271,15 @@ static u32 flow_get_skgid(const struct sk_buff *skb) return 0; } +static u32 flow_get_vlan_tag(const struct sk_buff *skb) +{ + u16 uninitialized_var(tag); + + if (vlan_get_tag(skb, &tag) < 0) + return 0; + return tag & VLAN_VID_MASK; +} + static u32 flow_key_get(const struct sk_buff *skb, int key) { switch (key) { @@ -305,6 +315,8 @@ static u32 flow_key_get(const struct sk_buff *skb, int key) return flow_get_skuid(skb); case FLOW_KEY_SKGID: return flow_get_skgid(skb); + case FLOW_KEY_VLAN_TAG: + return flow_get_vlan_tag(skb); default: WARN_ON(1); return 0; @@ -402,12 +414,13 @@ static int flow_change(struct tcf_proto *tp, unsigned long base, if (tb[TCA_FLOW_KEYS]) { keymask = nla_get_u32(tb[TCA_FLOW_KEYS]); - if (fls(keymask) - 1 > FLOW_KEY_MAX) - return -EOPNOTSUPP; nkeys = hweight32(keymask); if (nkeys == 0) return -EINVAL; + + if (fls(keymask) - 1 > FLOW_KEY_MAX) + return -EOPNOTSUPP; } err = tcf_exts_validate(tp, tb, tca[TCA_RATE], &e, &flow_ext_map); @@ -594,11 +607,11 @@ static int flow_dump(struct tcf_proto *tp, unsigned long fh, if (tcf_exts_dump(skb, &f->exts, &flow_ext_map) < 0) goto nla_put_failure; - +#ifdef CONFIG_NET_EMATCH if (f->ematches.hdr.nmatches && tcf_em_tree_dump(skb, &f->ematches, TCA_FLOW_EMATCHES) < 0) goto nla_put_failure; - +#endif nla_nest_end(skb, nest); if (tcf_exts_dump_stats(skb, &f->exts, &flow_ext_map) < 0) diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c index a1e5619..2a7e648 100644 --- a/net/sched/em_meta.c +++ b/net/sched/em_meta.c @@ -65,6 +65,7 @@ #include <linux/string.h> #include <linux/skbuff.h> #include <linux/random.h> +#include <linux/if_vlan.h> #include <linux/tc_ematch/tc_em_meta.h> #include <net/dst.h> #include <net/route.h> @@ -170,6 +171,21 @@ META_COLLECTOR(var_dev) } /************************************************************************** + * vlan tag + **************************************************************************/ + +META_COLLECTOR(int_vlan_tag) +{ + unsigned short uninitialized_var(tag); + if (vlan_get_tag(skb, &tag) < 0) + *err = -1; + else + dst->value = tag; +} + + + +/************************************************************************** * skb attributes **************************************************************************/ @@ -520,6 +536,7 @@ static struct meta_ops __meta_ops[TCF_META_TYPE_MAX+1][TCF_META_ID_MAX+1] = { [META_ID(SK_SNDTIMEO)] = META_FUNC(int_sk_sndtimeo), [META_ID(SK_SENDMSG_OFF)] = META_FUNC(int_sk_sendmsg_off), [META_ID(SK_WRITE_PENDING)] = META_FUNC(int_sk_write_pend), + [META_ID(VLAN_TAG)] = META_FUNC(int_vlan_tag), } }; diff --git a/net/sctp/auth.c b/net/sctp/auth.c index 97e6ebd..ae367c8 100644 --- a/net/sctp/auth.c +++ b/net/sctp/auth.c @@ -420,15 +420,15 @@ struct sctp_shared_key *sctp_auth_get_shkey( const struct sctp_association *asoc, __u16 key_id) { - struct sctp_shared_key *key = NULL; + struct sctp_shared_key *key; /* First search associations set of endpoint pair shared keys */ key_for_each(key, &asoc->endpoint_shared_keys) { if (key->key_id == key_id) - break; + return key; } - return key; + return NULL; } /* diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 5df0c4b..f986587 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c @@ -3865,6 +3865,10 @@ sctp_disposition_t sctp_sf_eat_auth(const struct sctp_endpoint *ep, struct sctp_chunk *err_chunk; sctp_ierror_t error; + /* Make sure that the peer has AUTH capable */ + if (!asoc->peer.auth_capable) + return sctp_sf_unk_chunk(ep, asoc, type, arg, commands); + if (!sctp_vtag_verify(chunk, asoc)) { sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG, SCTP_NULL()); |