--- a/netlink/include/nss_nldtls_if.h +++ b/netlink/include/nss_nldtls_if.h @@ -34,9 +34,9 @@ #define NSS_NLDTLS_DECAP_SIDE 1 #define NSS_NLDTLS_TX_PKTS_MODE_END_TO_END 0 #define NSS_NLDTLS_TX_PKTS_MODE_HOST_TO_HOST 1 -#define NSS_NLDTLS_CKD_MAX 32 -#define NSS_NLDTLS_AKD_MAX 32 -#define NSS_NLDTLS_ND_MAX 20 +#define NSS_NLDTLS_CIPHER_KEY_MAX 32 +#define NSS_NLDTLS_AUTH_KEY_MAX 64 +#define NSS_NLDTLS_NONCE_SIZE_MAX 4 /** * @brief Enumeration for all command types. @@ -51,11 +51,36 @@ enum nss_nldtls_cmd_type { }; /** + * @brief Parameters for crypto keys + */ +struct nss_nldtls_crypto_keys { + uint8_t cipher[NSS_NLDTLS_CIPHER_KEY_MAX]; /**< Cipher key data */ + uint8_t auth[NSS_NLDTLS_CIPHER_KEY_MAX]; /**< Cipher key data */ + uint8_t nonce[NSS_NLDTLS_CIPHER_KEY_MAX]; /**< Cipher key data */ +}; + +/** + * @brief Parameters for encap configuration + */ +struct nss_nldtls_encap_config { + struct nss_dtlsmgr_encap_config cfg; + struct nss_nldtls_crypto_keys keys; +}; + +/** + * @brief Parameter for decap configuration + */ +struct nss_nldtls_decap_config { + struct nss_dtlsmgr_decap_config cfg; + struct nss_nldtls_crypto_keys keys; +}; + +/** * @brief Parameters to create a tunnel. */ struct nss_nldtls_create_tun { - struct nss_dtlsmgr_encap_config encap; /**< Encap data. */ - struct nss_dtlsmgr_decap_config decap; /**< Decap data. */ + struct nss_nldtls_encap_config encap; /**< Encap data. */ + struct nss_nldtls_decap_config decap; /**< Decap data. */ uint32_t flags; /**< DTLS header flags. */ uint32_t from_mtu; /**< Mtu of incoming interface. */ uint32_t to_mtu; /**< Mtu of outgoing interface. */ @@ -77,6 +102,7 @@ struct nss_nldtls_destroy_tun { */ struct nss_nldtls_update_config { struct nss_dtlsmgr_config_update config_update; /**< Update config params */ + struct nss_nldtls_crypto_keys keys; /**< Crypto keys. */ uint16_t epoch; /**< Dtls encap epoch. */ uint16_t window_sz; /**< Dtls window size parameter. */ char dev_name[IFNAMSIZ]; /**< Device whose config to be updated. */ @@ -88,10 +114,11 @@ struct nss_nldtls_update_config { */ struct nss_nldtls_tx_pkts { uint32_t num_pkts; /**< Number of packets to be transmitted */ + uint32_t seq_num; /**< starting sequence number */ uint16_t pkt_sz; /**< Size of packet to be transmitted */ char dev_name[IFNAMSIZ]; /**< Device used for transmission */ - uint8_t ip_version; /**< Ip version [4 or 6] */ uint8_t mode; /**< Can be end_to_end or host_to_host*/ + uint8_t ctype; /**< dtls content type */ bool log_en; /**< Enable or disable wireless info */ }; --- a/netlink/nss_nl.h +++ b/netlink/nss_nl.h @@ -1,6 +1,6 @@ /* ************************************************************************** - * Copyright (c) 2015,2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2015,2018, 2020, The Linux Foundation. All rights reserved. * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the * above copyright notice and this permission notice appear in all copies. @@ -25,6 +25,7 @@ #define NSS_NL_DEBUG_LVL_WARN 2 #define NSS_NL_DEBUG_LVL_INFO 3 #define NSS_NL_DEBUG_LVL_TRACE 4 +#define GENL_ID_GENERATE 0 #if defined(CONFIG_DYNAMIC_DEBUG) @@ -35,7 +36,8 @@ #define nss_nl_warn(s, ...) pr_debug("%s[%d]:" s, __func__, __LINE__, ##__VA_ARGS__) #define nss_nl_info(s, ...) pr_debug("%s[%d]:" s, __func__, __LINE__, ##__VA_ARGS__) #define nss_nl_trace(s, ...) pr_debug("%s[%d]:" s, __func__, __LINE__, ##__VA_ARGS__) - +#define nss_nl_hex_dump_bytes(prefix_str, prefix_type, buf, len) \ + dynamic_hex_dump(prefix_str, prefix_type, 16, 1, buf, len, true) #else /* * Statically compile messages at different levels @@ -55,6 +57,11 @@ pr_notice("%s[%d]:" s, __func__, __LINE__, ##__VA_ARGS__); \ } \ } +#define nss_nl_hex_dump_bytes(prefix_str, prefix_type, buf, len) { \ + if (NSS_NL_DEBUG_LEVEL > NSS_NL_DEBUG_LVL_INFO) { \ + print_hex_dump_bytes(prefix_str, prefix_type, buf, len); \ + } \ +} #define nss_nl_trace(s, ...) { \ if (NSS_NL_DEBUG_LEVEL > NSS_NL_DEBUG_LVL_TRACE) { \ pr_info("%s[%d]:" s, __func__, __LINE__, ##__VA_ARGS__); \ --- a/netlink/nss_nlc2c_rx.c +++ b/netlink/nss_nlc2c_rx.c @@ -46,20 +46,6 @@ static int nss_nlc2c_rx_ops_get_stats(st static int nss_nlc2c_rx_process_notify(struct notifier_block *nb, unsigned long val, void *data); /* - * c2c_rx family definition - */ -static struct genl_family nss_nlc2c_rx_family = { - .id = GENL_ID_GENERATE, /* Auto generate ID */ - .name = NSS_NLC2C_RX_FAMILY, /* family name string */ - .hdrsize = sizeof(struct nss_c2c_rx_stats_notification), /* NSS NETLINK c2c_rx stats */ - .version = NSS_NL_VER, /* Set it to NSS_NLC2C_RX version */ - .maxattr = NSS_STATS_EVENT_MAX, /* maximum commands supported */ - .netnsok = true, - .pre_doit = NULL, - .post_doit = NULL, -}; - -/* * multicast group for sending message status & events */ static const struct genl_multicast_group nss_nlc2c_rx_mcgrp[] = { @@ -74,6 +60,26 @@ static struct genl_ops nss_nlc2c_rx_ops[ }; /* + * c2c_rx family definition + */ +static struct genl_family nss_nlc2c_rx_family = { +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 9, 0)) + .id = GENL_ID_GENERATE, /* Auto generate ID */ +#endif + .name = NSS_NLC2C_RX_FAMILY, /* family name string */ + .hdrsize = sizeof(struct nss_c2c_rx_stats_notification), /* NSS NETLINK c2c_rx stats */ + .version = NSS_NL_VER, /* Set it to NSS_NLC2C_RX version */ + .maxattr = NSS_STATS_EVENT_MAX, /* maximum commands supported */ + .netnsok = true, + .pre_doit = NULL, + .post_doit = NULL, + .ops = nss_nlc2c_rx_ops, + .n_ops = ARRAY_SIZE(nss_nlc2c_rx_ops), + .mcgrps = nss_nlc2c_rx_mcgrp, + .n_mcgrps = ARRAY_SIZE(nss_nlc2c_rx_mcgrp) +}; + +/* * stats call back handler for c2c_rx from NSS */ static struct notifier_block nss_c2c_rx_stats_notifier_nb = { @@ -125,7 +131,7 @@ bool nss_nlc2c_rx_init(void) /* * register NETLINK ops with the family */ - error = genl_register_family_with_ops_groups(&nss_nlc2c_rx_family, nss_nlc2c_rx_ops, nss_nlc2c_rx_mcgrp); + error = genl_register_family(&nss_nlc2c_rx_family); if (error) { nss_nl_info_always("Error: unable to register c2c_rx family\n"); return false; --- a/netlink/nss_nlc2c_tx.c +++ b/netlink/nss_nlc2c_tx.c @@ -46,20 +46,6 @@ static int nss_nlc2c_tx_ops_get_stats(st static int nss_nlc2c_tx_process_notify(struct notifier_block *nb, unsigned long val, void *data); /* - * c2c_tx family definition - */ -static struct genl_family nss_nlc2c_tx_family = { - .id = GENL_ID_GENERATE, /* Auto generate ID */ - .name = NSS_NLC2C_TX_FAMILY, /* family name string */ - .hdrsize = sizeof(struct nss_c2c_tx_stats_notification), /* NSS NETLINK c2c_tx stats */ - .version = NSS_NL_VER, /* Set it to NSS_NLC2C_TX version */ - .maxattr = NSS_STATS_EVENT_MAX, /* maximum commands supported */ - .netnsok = true, - .pre_doit = NULL, - .post_doit = NULL, -}; - -/* * multicast group for sending message status & events */ static const struct genl_multicast_group nss_nlc2c_tx_mcgrp[] = { @@ -74,6 +60,26 @@ static struct genl_ops nss_nlc2c_tx_ops[ }; /* + * c2c_tx family definition + */ +static struct genl_family nss_nlc2c_tx_family = { +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 9, 0)) + .id = GENL_ID_GENERATE, /* Auto generate ID */ +#endif + .name = NSS_NLC2C_TX_FAMILY, /* family name string */ + .hdrsize = sizeof(struct nss_c2c_tx_stats_notification), /* NSS NETLINK c2c_tx stats */ + .version = NSS_NL_VER, /* Set it to NSS_NLC2C_TX version */ + .maxattr = NSS_STATS_EVENT_MAX, /* maximum commands supported */ + .netnsok = true, + .pre_doit = NULL, + .post_doit = NULL, + .ops = nss_nlc2c_tx_ops, + .n_ops = ARRAY_SIZE(nss_nlc2c_tx_ops), + .mcgrps = nss_nlc2c_tx_mcgrp, + .n_mcgrps = ARRAY_SIZE(nss_nlc2c_tx_mcgrp) +}; + +/* * stats call back handler for c2c_tx from NSS */ static struct notifier_block nss_c2c_tx_stats_notifier_nb = { @@ -125,7 +131,7 @@ bool nss_nlc2c_tx_init(void) /* * register NETLINK ops with the family */ - error = genl_register_family_with_ops_groups(&nss_nlc2c_tx_family, nss_nlc2c_tx_ops, nss_nlc2c_tx_mcgrp); + error = genl_register_family(&nss_nlc2c_tx_family); if (error) { nss_nl_info_always("Error: unable to register c2c_tx family\n"); return false; --- a/netlink/nss_nldtls.c +++ b/netlink/nss_nldtls.c @@ -15,6 +15,7 @@ */ #include +#include #include #include #include @@ -34,6 +35,14 @@ #include "nss_nldtls_if.h" /* + * prototypes + */ +static int nss_nldtls_ops_create_tun(struct sk_buff *skb, struct genl_info *info); +static int nss_nldtls_ops_destroy_tun(struct sk_buff *skb, struct genl_info *info); +static int nss_nldtls_ops_update_config(struct sk_buff *skb, struct genl_info *info); +static int nss_nldtls_ops_tx_pkts(struct sk_buff *skb, struct genl_info *info); + +/* * Initializing the global variables */ static struct nss_nldtls_gbl_ctx gbl_ctx = { @@ -52,11 +61,24 @@ static const struct genl_multicast_group }; /* + * nss_nldtls_ops + * Operation table called by the generic netlink layer based on the command + */ +static struct genl_ops nss_nldtls_ops[] = { + {.cmd = NSS_NLDTLS_CMD_TYPE_CREATE_TUN, .doit = nss_nldtls_ops_create_tun,}, + {.cmd = NSS_NLDTLS_CMD_TYPE_DESTROY_TUN, .doit = nss_nldtls_ops_destroy_tun,}, + {.cmd = NSS_NLDTLS_CMD_TYPE_UPDATE_CONFIG, .doit = nss_nldtls_ops_update_config,}, + {.cmd = NSS_NLDTLS_CMD_TYPE_TX_PKTS, .doit = nss_nldtls_ops_tx_pkts,}, +}; + +/* * nss_nldtls_family * Dtls family definition */ struct genl_family nss_nldtls_family = { +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 9, 0)) .id = GENL_ID_GENERATE, /* Auto generate ID */ +#endif .name = NSS_NLDTLS_FAMILY, /* family name string */ .hdrsize = sizeof(struct nss_nldtls_rule), /* NSS NETLINK dtls rule */ .version = NSS_NL_VER, /* Set it to NSS_NLDTLS version */ @@ -64,13 +86,17 @@ struct genl_family nss_nldtls_family = { .netnsok = true, .pre_doit = NULL, .post_doit = NULL, + .ops = nss_nldtls_ops, + .n_ops = ARRAY_SIZE(nss_nldtls_ops), + .mcgrps = nss_nldtls_family_mcgrp, + .n_mcgrps = ARRAY_SIZE(nss_nldtls_family_mcgrp) }; /* - * nss_nldtls_find_dtls_tun_gbl_ctx() + * nss_nldtls_find_tun_ctx() * Returns the global context object of a tunnel */ -static struct nss_nldtls_tun_ctx *nss_nldtls_find_dtls_tun_gbl_ctx(struct net_device *dev) +static struct nss_nldtls_tun_ctx *nss_nldtls_find_tun_ctx(struct net_device *dev) { struct nss_nldtls_tun_ctx *entry; @@ -87,47 +113,6 @@ static struct nss_nldtls_tun_ctx *nss_nl } /* - * nss_nldtls_data_cb() - * Data callback function for dtls - */ -static void __maybe_unused nss_nldtls_data_cb(void *app_data __maybe_unused, struct sk_buff *skb __maybe_unused) -{ - static bool first_pkt; - unsigned long long duration; - ktime_t delta; - - if (unlikely(!first_pkt)) { - gbl_ctx.first_rx_pkt_time = ktime_get(); - first_pkt = true; - } - - /* - * Remove meta header - */ - skb_pull(skb, sizeof(struct nss_dtlsmgr_metadata)); - gbl_ctx.last_rx_pkt_time = ktime_get(); - - if (unlikely(gbl_ctx.log_en)) { - struct net_device *dev; - - delta = ktime_sub(gbl_ctx.last_rx_pkt_time, gbl_ctx.first_rx_pkt_time); - duration = (unsigned long long) ktime_to_ns(delta) >> 10; - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, skb->data, 32); - dev = dev_get_by_index(&init_net, skb->skb_iif); - if (dev) { - nss_nl_error("In dev = %s, out_dev = %s\n", dev->name, skb->dev->name); - dev_put(dev); - } - - nss_nl_info("%px: DTLS RX (%s) pkt len = %d udp_csum = %s rx_time: %llu\n", skb, - skb->dev->name, skb->len, udp_lib_checksum_complete(skb) ? - "invalid" : "valid", duration); - } - - dev_kfree_skb_any(skb); -} - -/* * nss_nldtls_dev_rx_handler() * Common rx handler for all dtls dev */ @@ -416,6 +401,48 @@ static int nss_nldtls_create_ipv6_rule(s } /* + * nss_nldtls_data_callback() + * Data callback function for dtls + */ +static void nss_nldtls_data_callback(void *app_data, struct sk_buff *skb) +{ + struct nss_dtlsmgr_metadata *ndm; + struct nss_nldtls_tun_ctx *tun; + struct nss_nldtls_stats *stats; + struct net_device *dev; + + dev = dev_get_by_index(&init_net, skb->skb_iif); + if (!dev) { + nss_nl_error("Unable to get net dev for skb_iif %d\n", skb->skb_iif); + dev_kfree_skb_any(skb); + return; + } + + ndm = (struct nss_dtlsmgr_metadata *)skb->data; + tun = nss_nldtls_find_tun_ctx(dev); + if (!tun) { + nss_nl_error("Unable find tunnel ctx for %s\n", dev->name); + dev_put(dev); + dev_kfree_skb_any(skb); + return; + } + + stats = &tun->stats[NSS_NLDTLS_CTYPE_TO_IDX(ndm->ctype)]; + spin_lock(&gbl_ctx.lock); + stats->rx_pkts++; + stats->rx_bytes += skb->len - sizeof(*ndm); + spin_unlock(&gbl_ctx.lock); + + if (unlikely(gbl_ctx.log_en)) { + nss_nl_hex_dump_bytes("", DUMP_PREFIX_OFFSET, skb->data, (skb->len > 64) ? 64 : skb->len); + } + + nss_nl_trace("%px Received DTLS packet\n", skb); + dev_put(dev); + dev_kfree_skb_any(skb); +} + +/* * nss_nldtls_create_session() * Create a DTLS session through dtlsmgr driver API. */ @@ -425,6 +452,7 @@ static struct net_device *nss_nldtls_cre struct nss_dtlsmgr_config dcfg; struct nss_dtlsmgr_ctx *ctx; struct net_device *ndev; + uint16_t key_len; uint8_t algo; int err; @@ -434,24 +462,66 @@ static struct net_device *nss_nldtls_cre } memset(&dcfg, 0, sizeof(struct nss_dtlsmgr_config)); - algo = nl_rule->msg.create.encap.crypto.algo; - dcfg.flags = flags; + algo = nl_rule->msg.create.encap.cfg.crypto.algo; + dcfg.flags = flags | (NSS_DTLSMGR_ENCAP_METADATA | NSS_DTLSMGR_HDR_CAPWAP); if (algo == NSS_DTLSMGR_ALGO_AES_GCM) dcfg.flags |= NSS_DTLSMGR_CIPHER_MODE_GCM; dcfg.app_data = NULL; dcfg.notify = NULL; - dcfg.data = NULL; + dcfg.data = nss_nldtls_data_callback; /* * Encap configuration */ - memcpy((void *)&dcfg.encap, (void *)&nl_rule->msg.create.encap, sizeof(struct nss_dtlsmgr_encap_config)); + key_len = nl_rule->msg.create.encap.cfg.crypto.cipher_key.len; + if (key_len > NSS_NLDTLS_CIPHER_KEY_MAX) { + nss_nl_error("Invalid cipher length: %u\n", key_len); + return NULL; + } + + key_len = nl_rule->msg.create.encap.cfg.crypto.auth_key.len; + if (key_len > NSS_NLDTLS_AUTH_KEY_MAX) { + nss_nl_error("Invalid authentication length: %u\n", key_len); + return NULL; + } + + key_len = nl_rule->msg.create.encap.cfg.crypto.nonce.len; + if (key_len > NSS_NLDTLS_NONCE_SIZE_MAX) { + nss_nl_error("Invalid nonce length: %u\n", key_len); + return NULL; + } + + nl_rule->msg.create.encap.cfg.crypto.cipher_key.data = nl_rule->msg.create.encap.keys.cipher; + nl_rule->msg.create.encap.cfg.crypto.auth_key.data = nl_rule->msg.create.encap.keys.auth; + nl_rule->msg.create.encap.cfg.crypto.nonce.data = nl_rule->msg.create.encap.keys.nonce; + memcpy((void *)&dcfg.encap, (void *)&nl_rule->msg.create.encap.cfg, sizeof(struct nss_dtlsmgr_encap_config)); /* * Decap configuration */ - memcpy((void *)&dcfg.decap, (void *)&nl_rule->msg.create.decap, sizeof(struct nss_dtlsmgr_decap_config)); + key_len = nl_rule->msg.create.decap.cfg.crypto.cipher_key.len; + if (key_len > NSS_NLDTLS_CIPHER_KEY_MAX) { + nss_nl_error("Invalid cipher length: %u\n", key_len); + return NULL; + } + + key_len = nl_rule->msg.create.decap.cfg.crypto.auth_key.len; + if (key_len > NSS_NLDTLS_AUTH_KEY_MAX) { + nss_nl_error("Invalid authentication length: %u\n", key_len); + return NULL; + } + + key_len = nl_rule->msg.create.decap.cfg.crypto.nonce.len; + if (key_len > NSS_NLDTLS_NONCE_SIZE_MAX) { + nss_nl_error("Invalid nonce length: %u\n", key_len); + return NULL; + } + + nl_rule->msg.create.decap.cfg.crypto.cipher_key.data = nl_rule->msg.create.decap.keys.cipher; + nl_rule->msg.create.decap.cfg.crypto.auth_key.data = nl_rule->msg.create.decap.keys.auth; + nl_rule->msg.create.decap.cfg.crypto.nonce.data = nl_rule->msg.create.decap.keys.nonce; + memcpy((void *)&dcfg.decap, (void *)&nl_rule->msg.create.decap.cfg, sizeof(struct nss_dtlsmgr_decap_config)); dcfg.decap.nexthop_ifnum = NSS_N2H_INTERFACE; /* @@ -484,6 +554,7 @@ static struct net_device *nss_nldtls_cre dtls_tun_data = (struct nss_nldtls_tun_ctx *)kmalloc(sizeof(*dtls_tun_data), GFP_KERNEL); dtls_tun_data->nl_rule = nl_rule; memcpy(dtls_tun_data->dev_name, ndev->name, IFNAMSIZ); + memset(&dtls_tun_data->stats, 0, sizeof(dtls_tun_data->stats)); /* * Adding tunnel to global list of tunnels @@ -524,15 +595,15 @@ static int nss_nldtls_create_ipv4_rule_e ipv4.src_interface_num = if_num; ipv4.dest_interface_num = nss_dtlsmgr_get_interface(dtls_dev, NSS_DTLSMGR_INTERFACE_TYPE_OUTER); - ipv4.src_port = nl_rule->msg.create.encap.dport; - ipv4.src_port_xlate = nl_rule->msg.create.encap.dport; - ipv4.src_ip = nl_rule->msg.create.encap.dip[0]; - ipv4.src_ip_xlate = nl_rule->msg.create.encap.dip[0]; - - ipv4.dest_ip = nl_rule->msg.create.encap.sip[0]; - ipv4.dest_ip_xlate = nl_rule->msg.create.encap.sip[0]; - ipv4.dest_port = nl_rule->msg.create.encap.sport; - ipv4.dest_port_xlate = nl_rule->msg.create.encap.sport; + ipv4.src_port = nl_rule->msg.create.encap.cfg.dport; + ipv4.src_port_xlate = nl_rule->msg.create.encap.cfg.dport; + ipv4.src_ip = nl_rule->msg.create.encap.cfg.dip[0]; + ipv4.src_ip_xlate = nl_rule->msg.create.encap.cfg.dip[0]; + + ipv4.dest_ip = nl_rule->msg.create.encap.cfg.sip[0]; + ipv4.dest_ip_xlate = nl_rule->msg.create.encap.cfg.sip[0]; + ipv4.dest_port = nl_rule->msg.create.encap.cfg.sport; + ipv4.dest_port_xlate = nl_rule->msg.create.encap.cfg.sport; ipv4.protocol = IPPROTO_UDP; ipv4.in_vlan_tag[0] = NSS_NLDTLS_VLAN_INVALID; @@ -575,14 +646,14 @@ static int nss_nldtls_create_ipv6_rule_e if_num = nss_cmn_get_interface_number_by_dev(ndev); ipv6.src_interface_num = if_num; ipv6.dest_interface_num = nss_dtlsmgr_get_interface(dtls_dev, NSS_DTLSMGR_INTERFACE_TYPE_OUTER); - ipv6.src_port = nl_rule->msg.create.encap.dport; - ipv6.dest_port = nl_rule->msg.create.encap.sport; + ipv6.src_port = nl_rule->msg.create.encap.cfg.dport; + ipv6.dest_port = nl_rule->msg.create.encap.cfg.sport; /* * Configure IPv6 rule */ - memcpy(ipv6.src_ip, nl_rule->msg.create.encap.dip, sizeof(ipv6.src_ip)); - memcpy(ipv6.dest_ip, nl_rule->msg.create.encap.sip, sizeof(ipv6.dest_ip)); + memcpy(ipv6.src_ip, nl_rule->msg.create.encap.cfg.dip, sizeof(ipv6.src_ip)); + memcpy(ipv6.dest_ip, nl_rule->msg.create.encap.cfg.sip, sizeof(ipv6.dest_ip)); ipv6.protocol = IPPROTO_UDP; ipv6.in_vlan_tag[0] = NSS_NLDTLS_VLAN_INVALID; @@ -602,29 +673,27 @@ static int nss_nldtls_create_ipv6_rule_e * nss_nldtls_destroy_tun() * Common handler for tunnel destroy */ -static int nss_nldtls_destroy_tun(struct net_device *dtls_ndev) +static int nss_nldtls_destroy_tun(struct net_device *dev) { - struct nss_nldtls_tun_ctx *dtls_tun_data; + struct nss_nldtls_tun_ctx *tun; - dtls_tun_data = nss_nldtls_find_dtls_tun_gbl_ctx(dtls_ndev); - if (!dtls_tun_data) { - nss_nl_error("Unable to find context of the tunnel: %s\n", dtls_ndev->name); - dev_put(dtls_ndev); + tun = nss_nldtls_find_tun_ctx(dev); + if (!tun) { + nss_nl_error("Unable to find context of the tunnel: %s\n", dev->name); return -EAGAIN; } /* * Delete tunnel node from the list */ - list_del_init(&dtls_tun_data->list); - kfree(dtls_tun_data); - dev_put(dtls_ndev); + list_del_init(&tun->list); + kfree(tun); /* * Destroy the dtls session */ - if (nss_dtlsmgr_session_destroy(dtls_ndev)) { - nss_nl_error("Unable to destroy the tunnel: %s\n", dtls_ndev->name); + if (nss_dtlsmgr_session_destroy(dev)) { + nss_nl_error("Unable to destroy the tunnel: %s\n", dev->name); return -EAGAIN; } @@ -709,8 +778,8 @@ static int nss_nldtls_ops_create_tun(str static int nss_nldtls_ops_destroy_tun(struct sk_buff *skb, struct genl_info *info) { struct nss_nldtls_rule *nl_rule; - struct net_device *dtls_ndev; struct nss_nlcmn *nl_cm; + struct net_device *dev; int ret; /* @@ -727,18 +796,20 @@ static int nss_nldtls_ops_destroy_tun(st */ nl_rule = container_of(nl_cm, struct nss_nldtls_rule, cm); - dtls_ndev = dev_get_by_name(&init_net, nl_rule->msg.destroy.dev_name); - if (!dtls_ndev) { - nss_nl_error("%px: Unable to find dev: %s\n", skb, nl_rule->msg.destroy.dev_name); + dev = dev_get_by_name(&init_net, nl_rule->msg.destroy.dev_name); + if (!dev) { + nss_nl_error("%px Unable to find dev: %s\n", skb, nl_rule->msg.destroy.dev_name); return -EINVAL; } + dev_put(dev); + /* * Common dtls handler for tunnel destroy */ - ret = nss_nldtls_destroy_tun(dtls_ndev); + ret = nss_nldtls_destroy_tun(dev); if (ret < 0) { - nss_nl_error("%px: Unable to destroy tunnel: %s\n", skb, dtls_ndev->name); + nss_nl_error("%px Unable to destroy tunnel: %s\n", skb, dev->name); return -EAGAIN; } @@ -753,13 +824,14 @@ static int nss_nldtls_ops_destroy_tun(st */ static int nss_nldtls_ops_update_config(struct sk_buff *skb, struct genl_info *info) { - struct nss_nldtls_tun_ctx *dtls_tun_data; struct nss_dtlsmgr_config_update dcfg; struct nss_nldtls_rule *nl_rule; - struct net_device *dtls_ndev; + struct nss_nldtls_tun_ctx *tun; struct nss_dtlsmgr_ctx *ctx; nss_dtlsmgr_status_t status; struct nss_nlcmn *nl_cm; + struct net_device *dev; + uint16_t key_len; /* * extract the message payload @@ -775,17 +847,17 @@ static int nss_nldtls_ops_update_config( */ nl_rule = container_of(nl_cm, struct nss_nldtls_rule, cm); - dtls_ndev = dev_get_by_name(&init_net, nl_rule->msg.update_config.dev_name); - if (!dtls_ndev) { - nss_nl_error("%px: Unable to find dev: %s\n", skb, nl_rule->msg.update_config.dev_name); + dev = dev_get_by_name(&init_net, nl_rule->msg.update_config.dev_name); + if (!dev) { + nss_nl_error("%px Unable to find dev: %s\n", skb, nl_rule->msg.update_config.dev_name); return -EINVAL; } - ctx = netdev_priv(dtls_ndev); - dtls_tun_data = nss_nldtls_find_dtls_tun_gbl_ctx(dtls_ndev); - if (!dtls_tun_data) { - nss_nl_error("%px: Unable to find context of the tunnel: %s\n", ctx, dtls_ndev->name); - dev_put(dtls_ndev); + ctx = netdev_priv(dev); + tun = nss_nldtls_find_tun_ctx(dev); + if (!tun) { + nss_nl_error("%px Unable to find context of the tunnel: %s\n", ctx, dev->name); + dev_put(dev); return -EAGAIN; } @@ -793,28 +865,46 @@ static int nss_nldtls_ops_update_config( * Configure the dtls configuration */ dcfg.crypto.algo = nl_rule->msg.update_config.config_update.crypto.algo; - dcfg.crypto.cipher_key.data = nl_rule->msg.update_config.config_update.crypto.cipher_key.data; - dcfg.crypto.cipher_key.len = nl_rule->msg.update_config.config_update.crypto.cipher_key.len; - dcfg.crypto.auth_key.data = nl_rule->msg.update_config.config_update.crypto.auth_key.data; - dcfg.crypto.auth_key.len = nl_rule->msg.update_config.config_update.crypto.auth_key.len; - dcfg.crypto.nonce.data = nl_rule->msg.update_config.config_update.crypto.nonce.data; - dcfg.crypto.nonce.len = nl_rule->msg.update_config.config_update.crypto.nonce.len; + dcfg.crypto.cipher_key.data = nl_rule->msg.update_config.keys.cipher; + dcfg.crypto.auth_key.data = nl_rule->msg.update_config.keys.auth; + dcfg.crypto.nonce.data = nl_rule->msg.update_config.keys.nonce; + key_len = nl_rule->msg.update_config.config_update.crypto.cipher_key.len; + if (key_len > NSS_NLDTLS_CIPHER_KEY_MAX) { + nss_nl_error("Invalid cipher length: %u\n", key_len); + return -EINVAL; + } + + dcfg.crypto.cipher_key.len = key_len; + key_len = nl_rule->msg.update_config.config_update.crypto.auth_key.len; + if (key_len > NSS_NLDTLS_AUTH_KEY_MAX) { + nss_nl_error("Invalid authentication length: %u\n", key_len); + return -EINVAL; + } + + dcfg.crypto.auth_key.len = key_len; + key_len = nl_rule->msg.update_config.config_update.crypto.nonce.len; + if (key_len > NSS_NLDTLS_NONCE_SIZE_MAX) { + nss_nl_error("Invalid nonce length: %u\n", key_len); + return -EINVAL; + } + + dcfg.crypto.nonce.len = key_len; dcfg.epoch = nl_rule->msg.update_config.config_update.epoch; dcfg.window_size = nl_rule->msg.update_config.config_update.window_size; if (!nl_rule->msg.update_config.dir) { - status = nss_dtlsmgr_session_update_encap(dtls_ndev, &dcfg); + status = nss_dtlsmgr_session_update_encap(dev, &dcfg); if (status != NSS_DTLSMGR_OK) { - nss_nl_error("%px: Unable to update encap configuration\n", ctx); - dev_put(dtls_ndev); + nss_nl_error("%px Unable to update encap configuration\n", ctx); + dev_put(dev); return -EINVAL; } nss_nl_info("%px: Successfully update the encap configuration\n", ctx); } else { - status = nss_dtlsmgr_session_update_decap(dtls_ndev, &dcfg); + status = nss_dtlsmgr_session_update_decap(dev, &dcfg); if (status != NSS_DTLSMGR_OK) { - nss_nl_error("%px: Unable to update decap configuration\n", ctx); - dev_put(dtls_ndev); + nss_nl_error("%px Unable to update decap configuration\n", ctx); + dev_put(dev); return -EINVAL; } @@ -824,213 +914,65 @@ static int nss_nldtls_ops_update_config( /* * Update the tun data configuration */ - dtls_tun_data->nl_rule = nl_rule; + tun->nl_rule = nl_rule; + dev_put(dev); return 0; } /* - * nss_nldtls_construct_ipv4_udp_header() - * Creates an ipv4 + udp packet - */ -static struct sk_buff *nss_nldtls_construct_ipv4_udp_header(struct net_device *dev, struct nss_nldtls_rule *nl_rule) -{ - struct nss_nldtls_tun_ctx *tun_data; - struct nss_nldtls_rule *dtls_rule; - uint16_t hroom, troom; - struct sk_buff *skb; - struct udphdr *uh; - struct iphdr *iph; - - /* - * Get the tun data - */ - tun_data = nss_nldtls_find_dtls_tun_gbl_ctx(dev); - dtls_rule = tun_data->nl_rule; - hroom = dev->needed_headroom; - troom = dev->needed_tailroom; - skb = dev_alloc_skb(nl_rule->msg.tx_pkts.pkt_sz + hroom + troom); - if (!skb) { - nss_nl_info("Failed to allocate skb\n"); - return NULL; - } - - skb_reserve(skb, sizeof(struct udphdr) + sizeof(struct iphdr)); - skb_put(skb, nl_rule->msg.tx_pkts.pkt_sz); - - /* - * Fill the packet with dummy data - */ - memset(skb->data, NSS_NLDTLS_DUMMY_DATA, skb->len); - - /* - * Fill udp header fields - */ - skb_push(skb, sizeof(struct udphdr)); - uh = (struct udphdr *)skb->data; - uh->source = htons(dtls_rule->msg.create.encap.sport); - uh->dest = htons(dtls_rule->msg.create.encap.dport); - uh->len = htons(skb->len); - uh->check = 0; - - /* - * Fill IP header fields - */ - skb_push(skb, sizeof(struct iphdr)); - iph = (struct iphdr *)skb->data; - iph->ihl = 5; - iph->version = 4; - iph->tot_len = (nl_rule->msg.tx_pkts.pkt_sz + sizeof(struct udphdr) + sizeof(struct iphdr)); - iph->ttl = dtls_rule->msg.create.encap.ip_ttl; - iph->protocol = IPPROTO_UDP; - iph->saddr = dtls_rule->msg.create.encap.sip[0]; - iph->daddr = dtls_rule->msg.create.encap.dip[0]; - - /* - * UDP checksum - */ - uh->check = udp_csum(skb); - uh->check = csum_tcpudp_magic(iph->saddr, iph->daddr, skb->len, - IPPROTO_UDP, uh->check); - - if (nl_rule->msg.tx_pkts.log_en) { - nss_nl_info("%px: DTLS TX pkt len:%d udp_csum:0x%x\n", skb, skb->len, uh->check); - } - - return skb; -} - -/* - * nss_nldtls_construct_ipv6_udp_header() - * Creates an ipv6 + udp packet + * nss_nldtls_alloc_pkt() + * Handler for forming ctype packet */ -static struct sk_buff *nss_nldtls_construct_ipv6_udp_header(struct net_device *dev, struct nss_nldtls_rule *nl_rule) +static struct sk_buff *nss_nldtls_alloc_pkt(struct nss_nldtls_rule *nl_rule, + struct net_device *dev, uint32_t pkt_sz, uint8_t ctype) { - struct nss_nldtls_tun_ctx *tun_data; - struct nss_nldtls_rule *dtls_rule; - uint16_t hroom, troom; + struct nss_dtlsmgr_metadata *ndm; + uint16_t hdr_len, payload_len; struct sk_buff *skb; - struct udphdr *uh; - struct ipv6hdr *ip6h; - /* - * Get the tun data - */ - tun_data = nss_nldtls_find_dtls_tun_gbl_ctx(dev); - dtls_rule = tun_data->nl_rule; - hroom = dev->needed_headroom; - troom = dev->needed_tailroom; - skb = dev_alloc_skb(nl_rule->msg.tx_pkts.pkt_sz + hroom + troom); + hdr_len = dev->needed_headroom + sizeof(*ndm); + payload_len = hdr_len + dev->needed_tailroom + pkt_sz; + skb = netdev_alloc_skb(dev, payload_len); if (!skb) { - nss_nl_info("Failed to allocate skb\n"); return NULL; } - skb_reserve(skb, sizeof(struct udphdr) + sizeof(struct iphdr)); - skb_put(skb, nl_rule->msg.tx_pkts.pkt_sz); + skb_reserve(skb, hdr_len); /* * Fill the packet with dummy data */ - memset(skb->data, NSS_NLDTLS_DUMMY_DATA, skb->len); - - /* - * Fill udp header fields - */ - skb_push(skb, sizeof(struct udphdr)); - uh = (struct udphdr *)skb->data; - uh->source = htons(dtls_rule->msg.create.encap.sport); - uh->dest = htons(dtls_rule->msg.create.encap.dport); - uh->len = htons(skb->len); - uh->check = 0; + memset(skb_put(skb, pkt_sz), NSS_NLDTLS_DUMMY_DATA, skb->len); - /* - * Fill IP header fields - */ - skb_push(skb, sizeof(struct ipv6hdr)); - ip6h = (struct ipv6hdr *)skb->data; - ip6h->version = 6; - ip6h->payload_len = htons(nl_rule->msg.tx_pkts.pkt_sz + sizeof(struct udphdr)); - ip6h->hop_limit = 64; - ip6h->nexthdr = IPPROTO_UDP; - ip6h->saddr.in6_u.u6_addr32[0] = htonl(dtls_rule->msg.create.encap.sip[0]); - ip6h->saddr.in6_u.u6_addr32[1] = htonl(dtls_rule->msg.create.encap.sip[1]); - ip6h->saddr.in6_u.u6_addr32[2] = htonl(dtls_rule->msg.create.encap.sip[2]); - ip6h->saddr.in6_u.u6_addr32[3] = htonl(dtls_rule->msg.create.encap.sip[3]); + ndm = nss_dtlsmgr_metadata_init(skb); + nss_dtlsmgr_metadata_set_seq(ndm, nl_rule->msg.tx_pkts.seq_num); + nss_dtlsmgr_metadata_set_ctype(ndm, ctype); - ip6h->saddr.in6_u.u6_addr32[0] = htonl(dtls_rule->msg.create.encap.dip[0]); - ip6h->saddr.in6_u.u6_addr32[1] = htonl(dtls_rule->msg.create.encap.dip[1]); - ip6h->saddr.in6_u.u6_addr32[2] = htonl(dtls_rule->msg.create.encap.dip[2]); - ip6h->saddr.in6_u.u6_addr32[3] = htonl(dtls_rule->msg.create.encap.dip[3]); - - skb_set_transport_header(skb, sizeof(struct ipv6hdr)); - /* - * UDP checksum - */ - udp6_set_csum(false, skb, &ip6h->saddr, &ip6h->daddr, nl_rule->msg.tx_pkts.pkt_sz + sizeof(struct udphdr)); - - if (nl_rule->msg.tx_pkts.log_en) { - nss_nl_info("%px: DTLS TX pkt len:%d udp_csum:0x%x\n", skb, skb->len, uh->check); + if (unlikely(nl_rule->msg.tx_pkts.log_en)) { + nss_nl_info("%px DTLS TX pkt len:%u\n", skb, skb->len); } return skb; } /* - * nss_nldtls_tx_ipv4_pkts_host_to_host() - * Handler for sending ipv4 traffic from one host to other - */ -static bool nss_nldtls_tx_ipv4_pkts_host_to_host(struct nss_nldtls_rule *nl_rule, struct net_device *dtls_dev) -{ - int i; - for (i = 0; i < nl_rule->msg.tx_pkts.num_pkts; i++) { - struct sk_buff *skb; - - skb = nss_nldtls_construct_ipv4_udp_header(dtls_dev, nl_rule); - if (!skb) { - nss_nl_error("%px: Unable to create ipv4 + udp packet\n", dtls_dev); - return false; - } - - dtls_dev->netdev_ops->ndo_start_xmit(skb, dtls_dev); - } - - return true; -} - -/* - * nss_nldtls_tx_ipv6_pkts_host_to_host() - * Handler for sending ipv6 traffic from one host to other - */ -static bool nss_nldtls_tx_ipv6_pkts_host_to_host(struct nss_nldtls_rule *nl_rule, struct net_device *dtls_dev) -{ - int i; - for (i = 0; i < nl_rule->msg.tx_pkts.num_pkts; i++) { - struct sk_buff *skb; - - skb = nss_nldtls_construct_ipv6_udp_header(dtls_dev, nl_rule); - if (!skb) { - nss_nl_error("%px: Unable to create ipv4 + udp packet\n", dtls_dev); - return false; - } - - dtls_dev->netdev_ops->ndo_start_xmit(skb, dtls_dev); - } - - return true; -} - -/* * nss_nldtls_ops_tx_pkts() * Handler for sending traffic */ static int nss_nldtls_ops_tx_pkts(struct sk_buff *skb, struct genl_info *info) { - struct nss_nldtls_tun_ctx *dtls_tun_data; struct nss_nldtls_rule *nl_rule; - struct net_device *dtls_ndev; + struct nss_nldtls_tun_ctx *tun; + struct nss_nldtls_stats *stats; unsigned long long duration; struct nss_nlcmn *nl_cm; + struct net_device *dev; + struct sk_buff *tx_skb; + uint32_t num_pkts; + uint32_t pkt_sz; + uint32_t count; ktime_t delta; + uint8_t ctype; /* * extract the message payload @@ -1046,56 +988,149 @@ static int nss_nldtls_ops_tx_pkts(struct */ nl_rule = container_of(nl_cm, struct nss_nldtls_rule, cm); - dtls_ndev = dev_get_by_name(&init_net, nl_rule->msg.tx_pkts.dev_name); - if (!dtls_ndev) { - nss_nl_error("%px: Unable to find dev: %s\n", skb, nl_rule->msg.tx_pkts.dev_name); + ctype = nl_rule->msg.tx_pkts.ctype; + num_pkts = nl_rule->msg.tx_pkts.num_pkts; + + switch (ctype) { + case NSS_DTLSMGR_METADATA_CTYPE_CCS: + pkt_sz = NSS_NLDTLS_CCS_PKT_SZ; + break; + + case NSS_DTLSMGR_METADATA_CTYPE_ALERT: + pkt_sz = NSS_NLDTLS_ALERT_PKT_SZ; + break; + + case NSS_DTLSMGR_METADATA_CTYPE_HANDSHAKE: + pkt_sz = NSS_NLDTLS_HANDSHAKE_PKT_SZ; + break; + + case NSS_DTLSMGR_METADATA_CTYPE_APP: + pkt_sz = nl_rule->msg.tx_pkts.pkt_sz; + break; + + default: return -EINVAL; } - dtls_tun_data = nss_nldtls_find_dtls_tun_gbl_ctx(dtls_ndev); - if (!dtls_tun_data) { - nss_nl_error("%px: Unable to find context of the tunnel: %s\n", skb, dtls_ndev->name); - dev_put(dtls_ndev); - return -EAGAIN; + dev = dev_get_by_name(&init_net, nl_rule->msg.tx_pkts.dev_name); + if (!dev) { + nss_nl_error("%px Unable to find dev: %s\n", skb, nl_rule->msg.tx_pkts.dev_name); + return -EINVAL; + } + + tun = nss_nldtls_find_tun_ctx(dev); + if (!tun) { + nss_nl_error("%px Unable to find context of the tunnel: %s\n", skb, dev->name); + dev_put(dev); + return -EINVAL; } spin_lock(&gbl_ctx.lock); gbl_ctx.log_en = nl_rule->msg.tx_pkts.log_en; spin_unlock(&gbl_ctx.lock); - /* - * Send traffic from host to host - */ gbl_ctx.first_tx_pkt_time = ktime_get(); - if (nl_rule->msg.tx_pkts.ip_version == NSS_NLDTLS_IP_VERS_4) { - if (!nss_nldtls_tx_ipv4_pkts_host_to_host(nl_rule, dtls_ndev)) { - nss_nl_error("%px: Error in transmission\n", skb); - return -EAGAIN; - } - } else { - if (!nss_nldtls_tx_ipv6_pkts_host_to_host(nl_rule, dtls_ndev)) { - nss_nl_error("%px: Error in transmission\n", skb); - return -EAGAIN; + + for (count = 0; count < num_pkts; count++) { + tx_skb = nss_nldtls_alloc_pkt(nl_rule, dev, pkt_sz, ctype); + if (!tx_skb) { + nss_nl_error("%px Failed to allocate skb\n", dev); + break; } + + dev->netdev_ops->ndo_start_xmit(tx_skb, dev); + } + + stats = &tun->stats[NSS_NLDTLS_CTYPE_TO_IDX(ctype)]; + spin_lock(&gbl_ctx.lock); + stats->tx_pkts += count; + stats->tx_bytes += (count * pkt_sz); + spin_unlock(&gbl_ctx.lock); + dev_put(dev); + + if (count != num_pkts) { + nss_nl_error("%px Error in transmission\n", skb); + return -EAGAIN; } gbl_ctx.last_tx_pkt_time = ktime_get(); delta = ktime_sub(gbl_ctx.last_tx_pkt_time, gbl_ctx.first_tx_pkt_time); duration = (unsigned long long) ktime_to_ns(delta) >> 10; - nss_nl_info("%px: Packets sent in %llu usecs", dtls_ndev, duration); - nss_nl_info("%px: Traffic transmission successful\n", skb); + nss_nl_info("%px Packets sent in %llu usecs", dev, duration); + nss_nl_info("%px Traffic transmission successful\n", skb); return 0; } /* - * nss_nldtls_cmd_ops - * Operation table called by the generic netlink layer based on the command + * nss_nldtls_tunnel_stats_read() + * reads the per tunnel tx and rx packets stats for every ctypes */ -struct genl_ops nss_nldtls_cmd_ops[] = { - {.cmd = NSS_NLDTLS_CMD_TYPE_CREATE_TUN, .doit = nss_nldtls_ops_create_tun,}, - {.cmd = NSS_NLDTLS_CMD_TYPE_DESTROY_TUN, .doit = nss_nldtls_ops_destroy_tun,}, - {.cmd = NSS_NLDTLS_CMD_TYPE_UPDATE_CONFIG, .doit = nss_nldtls_ops_update_config,}, - {.cmd = NSS_NLDTLS_CMD_TYPE_TX_PKTS, .doit = nss_nldtls_ops_tx_pkts,}, +static ssize_t nss_nldtls_tunnel_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *f_ppos) +{ + struct nss_nldtls_stats stats[NSS_NLDTLS_CTYPE_MAX]; + struct nss_nldtls_tun_ctx *entry; + uint32_t max_output_lines; + char dev_name[IFNAMSIZ]; + ssize_t bytes_read = 0; + ssize_t size_wr = 0; + ssize_t size_al; + char *lbuf; + + max_output_lines = 2 + (NSS_NLDTLS_MAX_TUNNELS * NSS_NLDTLS_STATS_MAX_ROW); + size_al = NSS_NLDTLS_STATS_MAX_STR_LEN * max_output_lines; + + lbuf = vzalloc(size_al); + + if (!lbuf) { + nss_nl_error("%px Could not allocate buffer for debug entry\n", f_ppos); + return 0; + } + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nDTLS netlink ctype stats:\n"); + list_for_each_entry(entry, &gbl_ctx.dtls_list_head, list) { + spin_lock_bh(&gbl_ctx.lock); + memcpy(&stats, &entry->stats, sizeof(stats)); + strlcpy(dev_name, entry->dev_name, IFNAMSIZ); + spin_unlock_bh(&gbl_ctx.lock); + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n--------------------------------"); + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n%s:\t %s", "dev", dev_name); + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n change_cipher_spec"); + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n\t%s:\t %llu", "tx_pkts", stats[0].tx_pkts); + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n\t%s:\t %llu", "tx_bytes", stats[0].tx_bytes); + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n\t%s:\t %llu", "rx_pkts", stats[0].rx_pkts); + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n\t%s:\t %llu", "rx_bytes", stats[0].rx_bytes); + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n alert"); + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n\t%s:\t %llu", "tx_pkts", stats[1].tx_pkts); + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n\t%s:\t %llu", "tx_bytes", stats[1].tx_bytes); + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n\t%s:\t %llu", "rx_pkts", stats[1].rx_pkts); + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n\t%s:\t %llu", "rx_bytes", stats[1].rx_bytes); + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n handshake"); + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n\t%s:\t %llu", "tx_pkts", stats[2].tx_pkts); + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n\t%s:\t %llu", "tx_bytes", stats[2].tx_bytes); + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n\t%s:\t %llu", "rx_pkts", stats[2].rx_pkts); + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n\t%s:\t %llu", "rx_bytes", stats[2].rx_bytes); + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n app_data"); + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n\t%s:\t %llu", "tx_pkts", stats[3].tx_pkts); + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n\t%s:\t %llu", "tx_bytes", stats[3].tx_bytes); + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n\t%s:\t %llu", "rx_pkts", stats[3].rx_pkts); + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n\t%s:\t %llu", "rx_bytes", stats[3].rx_bytes); + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n--------------------------------\n"); + } + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nDTLS netlink ctype stats end\n\n"); + bytes_read = simple_read_from_buffer(ubuf, sz, f_ppos, lbuf, size_wr); + + vfree(lbuf); + return bytes_read; +} + +/* + * nss_nldtls_stats_ops() + * file operation handler for dentry + */ +static const struct file_operations nss_nldtls_stats_ops = { + .read = nss_nldtls_tunnel_stats_read, }; /* @@ -1111,14 +1146,35 @@ bool nss_nldtls_init(void) /* * register NETLINK ops with the family */ - err = genl_register_family_with_ops_groups(&nss_nldtls_family, nss_nldtls_cmd_ops, nss_nldtls_family_mcgrp); + err = genl_register_family(&nss_nldtls_family); if (err) { nss_nl_info_always("Error: %d unable to register gre_redir family\n", err); genl_unregister_family(&nss_nldtls_family); return false; } + /* + * Create a debugfs entry for netlink dtls + */ + gbl_ctx.dentry = debugfs_create_dir("nldtls", NULL); + if (!gbl_ctx.dentry) { + nss_nl_info_always("Cannot create nldtls directory\n"); + goto free_family; + } + + if (!debugfs_create_file("stats", 0400, gbl_ctx.dentry, NULL, &nss_nldtls_stats_ops)) { + nss_nl_info_always("Cannot create nldtls dentry file\n"); + goto free_debugfs; + } + return true; + +free_debugfs: + debugfs_remove_recursive(gbl_ctx.dentry); +free_family: + genl_unregister_family(&nss_nldtls_family); + + return false; } /* @@ -1128,7 +1184,7 @@ bool nss_nldtls_init(void) bool nss_nldtls_exit(void) { struct nss_nldtls_tun_ctx *entry, *tmp; - struct net_device *dtls_ndev; + struct net_device *dev; int err; nss_nl_info_always("Exit NSS netlink dtls handler\n"); @@ -1137,9 +1193,10 @@ bool nss_nldtls_exit(void) * Destroy all active tunnel before exiting */ list_for_each_entry_safe(entry, tmp, &gbl_ctx.dtls_list_head, list) { - dtls_ndev = dev_get_by_name(&init_net, entry->dev_name); - if (dtls_ndev) { - nss_nldtls_destroy_tun(dtls_ndev); + dev = dev_get_by_name(&init_net, entry->dev_name); + if (dev) { + dev_put(dev); + nss_nldtls_destroy_tun(dev); } } --- a/netlink/nss_nldtls.h +++ b/netlink/nss_nldtls.h @@ -27,6 +27,27 @@ #define NSS_NLDTLS_VLAN_INVALID 0xFFF #define NSS_NLDTLS_IP_VERS_4 4 #define NSS_NLDTLS_DUMMY_DATA 0xcc +#define NSS_NLDTLS_STATS_MAX_ROW 23 +#define NSS_NLDTLS_STATS_MAX_STR_LEN 35 + +#define NSS_NLDTLS_CTYPE_MAX 4 +#define NSS_NLDTLS_CTYPE_BASE NSS_DTLSMGR_METADATA_CTYPE_CCS +#define NSS_NLDTLS_CTYPE_TO_IDX(ctype) ((ctype) - NSS_NLDTLS_CTYPE_BASE) + +#define NSS_NLDTLS_CCS_PKT_SZ 1 +#define NSS_NLDTLS_ALERT_PKT_SZ 2 +#define NSS_NLDTLS_HANDSHAKE_PKT_SZ 56 + +/* + * nss_dtls_stats + * netlink DTLS TX and RX statistics + */ +struct nss_nldtls_stats { + uint64_t rx_pkts; + uint64_t rx_bytes; + uint64_t tx_pkts; + uint64_t tx_bytes; +}; /* * nss_nldtls_tun_ctx @@ -36,6 +57,8 @@ struct nss_nldtls_tun_ctx { struct list_head list; /**< List for holding different tunnel info */ struct nss_nldtls_rule *nl_rule; /**< Dtls rule structure */ char dev_name[IFNAMSIZ]; /**< Dtls session netdev */ + struct nss_nldtls_stats stats[NSS_NLDTLS_CTYPE_MAX]; + /**< Dtls stats */ }; /* @@ -51,6 +74,7 @@ struct nss_nldtls_gbl_ctx { ktime_t first_tx_pkt_time; ktime_t last_rx_pkt_time; ktime_t last_tx_pkt_time; + struct dentry *dentry; }; #if (CONFIG_NSS_NLDTLS == 1) --- a/netlink/nss_nldynamic_interface.c +++ b/netlink/nss_nldynamic_interface.c @@ -46,20 +46,6 @@ static int nss_nldynamic_interface_ops_g static int nss_nldynamic_interface_process_notify(struct notifier_block *nb, unsigned long val, void *data); /* - * dynamic interface family definition - */ -static struct genl_family nss_nldynamic_interface_family = { - .id = GENL_ID_GENERATE, /* Auto generate ID */ - .name = NSS_NLDYNAMIC_INTERFACE_FAMILY, /* family name string */ - .hdrsize = sizeof(struct nss_dynamic_interface_notification), /* NSS NETLINK dynamic interface information */ - .version = NSS_NL_VER, /* Set it to NSS_NLDYNAMIC_INTERFACE version */ - .maxattr = NSS_STATS_EVENT_MAX, /* maximum commands supported */ - .netnsok = true, - .pre_doit = NULL, - .post_doit = NULL, -}; - -/* * multicast group for sending message status & events */ static const struct genl_multicast_group nss_nldynamic_interface_mcgrp[] = { @@ -74,6 +60,26 @@ static struct genl_ops nss_nldynamic_int }; /* + * dynamic interface family definition + */ +static struct genl_family nss_nldynamic_interface_family = { +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 9, 0)) + .id = GENL_ID_GENERATE, /* Auto generate ID */ +#endif + .name = NSS_NLDYNAMIC_INTERFACE_FAMILY, /* family name string */ + .hdrsize = sizeof(struct nss_dynamic_interface_notification), /* NSS NETLINK dynamic interface information */ + .version = NSS_NL_VER, /* Set it to NSS_NLDYNAMIC_INTERFACE version */ + .maxattr = NSS_STATS_EVENT_MAX, /* maximum commands supported */ + .netnsok = true, + .pre_doit = NULL, + .post_doit = NULL, + .ops = nss_nldynamic_interface_ops, + .n_ops = ARRAY_SIZE(nss_nldynamic_interface_ops), + .mcgrps = nss_nldynamic_interface_mcgrp, + .n_mcgrps = ARRAY_SIZE(nss_nldynamic_interface_mcgrp) +}; + +/* * destroy interface call back handler for dynamic interface from NSS */ static struct notifier_block nss_dynamic_interface_stats_notifier_nb = { @@ -125,7 +131,7 @@ bool nss_nldynamic_interface_init(void) /* * register NETLINK ops with the family */ - error = genl_register_family_with_ops_groups(&nss_nldynamic_interface_family, nss_nldynamic_interface_ops, nss_nldynamic_interface_mcgrp); + error = genl_register_family(&nss_nldynamic_interface_family); if (error) { nss_nl_info_always("Error: unable to register dynamic_interface family\n"); return false; --- a/netlink/nss_nledma.c +++ b/netlink/nss_nledma.c @@ -45,20 +45,6 @@ static int nss_nledma_ops_get_stats(stru static int nss_nledma_process_notify(struct notifier_block *nb, unsigned long val, void *data); /* - * Edma family definition - */ -static struct genl_family nss_nledma_family = { - .id = GENL_ID_GENERATE, /* Auto generate ID */ - .name = NSS_NLEDMA_FAMILY, /* family name string */ - .hdrsize = sizeof(struct nss_nledma_stats), /* NSS NETLINK Edma stats */ - .version = NSS_NL_VER, /* Set it to NSS_NLEDMA version */ - .maxattr = NSS_STATS_EVENT_MAX, /* maximum commands supported */ - .netnsok = true, - .pre_doit = NULL, - .post_doit = NULL, -}; - -/* * multicast group for sending message status & events */ static const struct genl_multicast_group nss_nledma_mcgrp[] = { @@ -73,6 +59,26 @@ static struct genl_ops nss_nledma_ops[] }; /* + * Edma family definition + */ +static struct genl_family nss_nledma_family = { +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 9, 0)) + .id = GENL_ID_GENERATE, /* Auto generate ID */ +#endif + .name = NSS_NLEDMA_FAMILY, /* family name string */ + .hdrsize = sizeof(struct nss_nledma_stats), /* NSS NETLINK Edma stats */ + .version = NSS_NL_VER, /* Set it to NSS_NLEDMA version */ + .maxattr = NSS_STATS_EVENT_MAX, /* maximum commands supported */ + .netnsok = true, + .pre_doit = NULL, + .post_doit = NULL, + .ops = nss_nledma_ops, + .n_ops = ARRAY_SIZE(nss_nledma_ops), + .mcgrps = nss_nledma_mcgrp, + .n_mcgrps = ARRAY_SIZE(nss_nledma_mcgrp) +}; + +/* * statistics call back handler for edma from NSS */ static struct notifier_block nss_edma_stats_notifier_nb = { @@ -130,7 +136,7 @@ bool nss_nledma_init(void) /* * register NETLINK ops with the family */ - error = genl_register_family_with_ops_groups(&nss_nledma_family, nss_nledma_ops, nss_nledma_mcgrp); + error = genl_register_family(&nss_nledma_family); if (error) { nss_nl_info_always("Error: unable to register Edma family\n"); return false; --- a/netlink/nss_nlethrx.c +++ b/netlink/nss_nlethrx.c @@ -46,20 +46,6 @@ static int nss_nlethrx_ops_get_stats(str static int nss_nlethrx_process_notify(struct notifier_block *nb, unsigned long val, void *data); /* - * eth_rx family definition - */ -static struct genl_family nss_nlethrx_family = { - .id = GENL_ID_GENERATE, /* Auto generate ID */ - .name = NSS_NLETHRX_FAMILY, /* family name string */ - .hdrsize = sizeof(struct nss_eth_rx_stats_notification), /* NSS NETLINK eth_rx rule */ - .version = NSS_NL_VER, /* Set it to NSS_NLETHRX version */ - .maxattr = NSS_STATS_EVENT_MAX, /* maximum commands supported */ - .netnsok = true, - .pre_doit = NULL, - .post_doit = NULL, -}; - -/* * multicast group for sending message status & events */ static const struct genl_multicast_group nss_nlethrx_mcgrp[] = { @@ -74,6 +60,26 @@ static struct genl_ops nss_nlethrx_ops[] }; /* + * eth_rx family definition + */ +static struct genl_family nss_nlethrx_family = { +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 9, 0)) + .id = GENL_ID_GENERATE, /* Auto generate ID */ +#endif + .name = NSS_NLETHRX_FAMILY, /* family name string */ + .hdrsize = sizeof(struct nss_eth_rx_stats_notification), /* NSS NETLINK eth_rx rule */ + .version = NSS_NL_VER, /* Set it to NSS_NLETHRX version */ + .maxattr = NSS_STATS_EVENT_MAX, /* maximum commands supported */ + .netnsok = true, + .pre_doit = NULL, + .post_doit = NULL, + .ops = nss_nlethrx_ops, + .n_ops = ARRAY_SIZE(nss_nlethrx_ops), + .mcgrps = nss_nlethrx_mcgrp, + .n_mcgrps = ARRAY_SIZE(nss_nlethrx_mcgrp) +}; + +/* * statistics call back handler for eth_rx from NSS */ static struct notifier_block nss_eth_rx_stats_notifier_nb = { @@ -125,7 +131,7 @@ bool nss_nlethrx_init(void) /* * register NETLINK ops with the family */ - error = genl_register_family_with_ops_groups(&nss_nlethrx_family, nss_nlethrx_ops, nss_nlethrx_mcgrp); + error = genl_register_family(&nss_nlethrx_family); if (error) { nss_nl_info_always("Error: unable to register eth_rx family\n"); return false; --- a/netlink/nss_nlgre_redir_cmd.c +++ b/netlink/nss_nlgre_redir_cmd.c @@ -43,11 +43,46 @@ static DEFINE_SPINLOCK(lock); static enum nss_nlgre_redir_cmd_deploy_mode deploy_mode; /* + * prototypes + */ +static int nss_nlgre_redir_cmd_ops_tun_create(struct sk_buff *skb, struct genl_info *info); +static int nss_nlgre_redir_cmd_ops_tun_destroy(struct sk_buff *skb, struct genl_info *info); +static int nss_nlgre_redir_cmd_ops_map(struct sk_buff *skb, struct genl_info *info); +static int nss_nlgre_redir_cmd_ops_unmap(struct sk_buff *skb, struct genl_info *info); +static int nss_nlgre_redir_cmd_ops_set_next(struct sk_buff *skb, struct genl_info *info); +static int nss_nlgre_redir_cmd_ops_add_hash(struct sk_buff *skb, struct genl_info *info); +static int nss_nlgre_redir_cmd_ops_del_hash(struct sk_buff *skb, struct genl_info *info); + +/* + * nss_nlgre_redir_cmd_mcgrp + * Multicast group for sending message status & events + */ +static const struct genl_multicast_group nss_nlgre_redir_family_mcgrp[] = { + {.name = NSS_NLGRE_REDIR_MCAST_GRP}, +}; + +/* + * nss_nlgre_redir_ops + * Operation table called by the generic netlink layer based on the command + */ +static struct genl_ops nss_nlgre_redir_ops[] = { + {.cmd = NSS_NLGRE_REDIR_CMD_TYPE_CREATE_TUN, .doit = nss_nlgre_redir_cmd_ops_tun_create,}, + {.cmd = NSS_NLGRE_REDIR_CMD_TYPE_DESTROY_TUN, .doit = nss_nlgre_redir_cmd_ops_tun_destroy,}, + {.cmd = NSS_NLGRE_REDIR_CMD_TYPE_MAP, .doit = nss_nlgre_redir_cmd_ops_map,}, + {.cmd = NSS_NLGRE_REDIR_CMD_TYPE_UNMAP, .doit = nss_nlgre_redir_cmd_ops_unmap,}, + {.cmd = NSS_NLGRE_REDIR_CMD_TYPE_SET_NEXT_HOP, .doit = nss_nlgre_redir_cmd_ops_set_next,}, + {.cmd = NSS_NLGRE_REDIR_CMD_TYPE_ADD_HASH, .doit = nss_nlgre_redir_cmd_ops_add_hash,}, + {.cmd = NSS_NLGRE_REDIR_CMD_TYPE_DEL_HASH, .doit = nss_nlgre_redir_cmd_ops_del_hash,}, +}; + +/* * nss_nlgre_redir_cmd_family * Gre_redir family definition */ struct genl_family nss_nlgre_redir_cmd_family = { +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 9, 0)) .id = GENL_ID_GENERATE, /* Auto generate ID */ +#endif .name = NSS_NLGRE_REDIR_FAMILY, /* family name string */ .hdrsize = sizeof(struct nss_nlgre_redir_rule), /* NSS NETLINK gre_redir rule */ .version = NSS_NL_VER, /* Set it to NSS_NLGRE_REDIR version */ @@ -55,6 +90,10 @@ struct genl_family nss_nlgre_redir_cmd_f .netnsok = true, .pre_doit = NULL, .post_doit = NULL, + .ops = nss_nlgre_redir_ops, + .n_ops = ARRAY_SIZE(nss_nlgre_redir_ops), + .mcgrps = nss_nlgre_redir_family_mcgrp, + .n_mcgrps = ARRAY_SIZE(nss_nlgre_redir_family_mcgrp) }; /* @@ -134,7 +173,7 @@ done: } /* - * nss_nlgre_redir_cmd_ops_destroy_tun() + * nss_nlgre_redir_cmd_ops_tun_destroy() * Handler to destroy tunnel */ static int nss_nlgre_redir_cmd_ops_tun_destroy(struct sk_buff *skb, struct genl_info *info) @@ -287,7 +326,7 @@ static int nss_nlgre_redir_cmd_ops_unmap } /* - * nss_nlgre_redir_cmd_set_next() + * nss_nlgre_redir_cmd_ops_set_next() * Handler for set_next command */ static int nss_nlgre_redir_cmd_ops_set_next(struct sk_buff *skb, struct genl_info *info) @@ -340,7 +379,7 @@ done: } /* - * nss_nlgre_redir_cmd_add_hash() + * nss_nlgre_redir_cmd_ops_add_hash() * Handler for adding hash a value */ static int nss_nlgre_redir_cmd_ops_add_hash(struct sk_buff *skb, struct genl_info *info) @@ -373,7 +412,7 @@ static int nss_nlgre_redir_cmd_ops_add_h } /* - * nss_nlgre_redir_cmd_del_hash() + * nss_nlgre_redir_cmd_ops_del_hash() * Handler for deleting a hash value */ static int nss_nlgre_redir_cmd_ops_del_hash(struct sk_buff *skb, struct genl_info *info) @@ -410,20 +449,6 @@ static int nss_nlgre_redir_cmd_ops_del_h } /* - * nss_nlgre_redir_cmd_ops - * Operation table called by the generic netlink layer based on the command - */ -struct genl_ops nss_nlgre_redir_cmd_ops[] = { - {.cmd = NSS_NLGRE_REDIR_CMD_TYPE_CREATE_TUN, .doit = nss_nlgre_redir_cmd_ops_tun_create,}, - {.cmd = NSS_NLGRE_REDIR_CMD_TYPE_DESTROY_TUN, .doit = nss_nlgre_redir_cmd_ops_tun_destroy,}, - {.cmd = NSS_NLGRE_REDIR_CMD_TYPE_MAP, .doit = nss_nlgre_redir_cmd_ops_map,}, - {.cmd = NSS_NLGRE_REDIR_CMD_TYPE_UNMAP, .doit = nss_nlgre_redir_cmd_ops_unmap,}, - {.cmd = NSS_NLGRE_REDIR_CMD_TYPE_SET_NEXT_HOP, .doit = nss_nlgre_redir_cmd_ops_set_next,}, - {.cmd = NSS_NLGRE_REDIR_CMD_TYPE_ADD_HASH, .doit = nss_nlgre_redir_cmd_ops_add_hash,}, - {.cmd = NSS_NLGRE_REDIR_CMD_TYPE_DEL_HASH, .doit = nss_nlgre_redir_cmd_ops_del_hash,}, -}; - -/* * nss_nlgre_redir_cmd_get_ifnum() * Get the interface number corresponding to netdev */ --- a/netlink/nss_nlgre_redir_cmd.h +++ b/netlink/nss_nlgre_redir_cmd.h @@ -38,11 +38,6 @@ enum nss_nlgre_redir_cmd_deploy_mode { extern struct genl_family nss_nlgre_redir_cmd_family; /* - * Gre_redir generic netlink operations - */ -extern struct genl_ops nss_nlgre_redir_cmd_ops[NSS_NLGRE_REDIR_CMD_MAX]; - -/* * nss_nlgre_redir_cmd_get_ifnum() * Get the interface number corresponding to netdev */ --- a/netlink/nss_nlgre_redir_cmn.c +++ b/netlink/nss_nlgre_redir_cmn.c @@ -354,6 +354,24 @@ static struct rtnl_link_stats64 *nss_nlg } /* + * nss_nlgre_redir_cmn_dev_stats64 + * Report packet statistics to linux + */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0)) +static struct rtnl_link_stats64 *nss_nlgre_redir_cmn_dev_stats64(struct net_device *dev, + struct rtnl_link_stats64 *stats) +{ + return nss_nlgre_redir_cmn_get_stats64(dev, stats); +} +#else +static void nss_nlgre_redir_cmn_dev_stats64(struct net_device *dev, + struct rtnl_link_stats64 *stats) +{ + nss_nlgre_redir_cmn_get_stats64(dev, stats); +} +#endif + +/* * nss_nlgre_redir_cmn_set_mac_address() * Sets the mac address of netdev */ @@ -389,7 +407,11 @@ static void nss_nlgre_redir_cmn_dev_setu ether_setup(dev); dev->needed_headroom = NSS_NLGRE_REDIR_CMN_NEEDED_HEADROOM; dev->netdev_ops = &gre_redir_netdev_ops; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0)) dev->destructor = nss_nlgre_redir_cmn_netdev_destructor; +#else + dev->priv_destructor = nss_nlgre_redir_cmn_netdev_destructor; +#endif eth_hw_addr_random(dev); } @@ -401,7 +423,7 @@ static const struct net_device_ops gre_r .ndo_open = nss_nlgre_redir_cmn_open_interface, .ndo_stop = nss_nlgre_redir_cmn_close_interface, .ndo_start_xmit = nss_nlgre_redir_cmn_xmit_data, - .ndo_get_stats64 = nss_nlgre_redir_cmn_get_stats64, + .ndo_get_stats64 = nss_nlgre_redir_cmn_dev_stats64, .ndo_set_mac_address = nss_nlgre_redir_cmn_set_mac_address, }; --- a/netlink/nss_nlgre_redir_family.c +++ b/netlink/nss_nlgre_redir_family.c @@ -1,6 +1,6 @@ /* ************************************************************************** - * Copyright (c) 2015-2016,2018-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2016,2018-2020, The Linux Foundation. All rights reserved. * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the * above copyright notice and this permission notice appear in all copies. @@ -28,14 +28,6 @@ #include "nss_nlgre_redir_cmd.h" /* - * nss_nlgre_redir_cmd_mcgrp - * Multicast group for sending message status & events - */ -static const struct genl_multicast_group nss_nlgre_redir_family_mcgrp[] = { - {.name = NSS_NLGRE_REDIR_MCAST_GRP}, -}; - -/* * nss_nlgre_redir_family_init() * handler init */ @@ -47,7 +39,7 @@ bool nss_nlgre_redir_family_init(void) /* * register NETLINK ops with the family */ - err = genl_register_family_with_ops_groups(&nss_nlgre_redir_cmd_family, nss_nlgre_redir_cmd_ops, nss_nlgre_redir_family_mcgrp); + err = genl_register_family(&nss_nlgre_redir_cmd_family); if (err) { nss_nl_info_always("Error: %d unable to register gre_redir family\n", err); return false; --- a/netlink/nss_nlipsec.c +++ b/netlink/nss_nlipsec.c @@ -43,6 +43,16 @@ #include "nss_nlipv4_if.h" /* + * Function prototypes + */ +static int nss_nlipsec_op_create_tunnel(struct sk_buff *skb, struct genl_info *info); +static int nss_nlipsec_op_destroy_tunnel(struct sk_buff *skb, struct genl_info *info); +static int nss_nlipsec_op_add_sa(struct sk_buff *skb, struct genl_info *info); +static int nss_nlipsec_op_delete_sa(struct sk_buff *skb, struct genl_info *info); +// static int nss_nlipsec_op_add_flow(struct sk_buff *skb, struct genl_info *info); +// static int nss_nlipsec_op_delete_flow(struct sk_buff *skb, struct genl_info *info); + +/* * Hold netdevice references */ struct nss_nlipsec_ref { @@ -72,10 +82,49 @@ struct nss_nlipsec_ctx { static struct nss_nlipsec_ctx gbl_ctx; /* + * Multicast group for sending message status & events + */ +static const struct genl_multicast_group nss_nlipsec_mcgrp[] = { + {.name = NSS_NLIPSEC_MCAST_GRP}, +}; + +/* + * Operation table called by the generic netlink layer based on the command + */ +static struct genl_ops nss_nlipsec_ops[] = { + { /* Create tunnel */ + .cmd = NSS_NLIPSEC_CMD_ADD_TUNNEL, + .doit = nss_nlipsec_op_create_tunnel, + }, + { /* Destroy tunnel */ + .cmd = NSS_NLIPSEC_CMD_DEL_TUNNEL, + .doit = nss_nlipsec_op_destroy_tunnel, + }, + { /* Add Security Association */ + .cmd = NSS_NLIPSEC_CMD_ADD_SA, + .doit = nss_nlipsec_op_add_sa, + }, + { /* Delete Security Association */ + .cmd = NSS_NLIPSEC_CMD_DEL_SA, + .doit = nss_nlipsec_op_delete_sa, + }, + // { /* Add flow */ + // .cmd = NSS_NLIPSEC_CMD_ADD_FLOW, + // .doit = nss_nlipsec_op_add_flow, + // }, + // { /* Delete flow */ + // .cmd = NSS_NLIPSEC_CMD_DEL_FLOW, + // .doit = nss_nlipsec_op_delete_flow, + // }, +}; + +/* * IPsec family definition */ static struct genl_family nss_nlipsec_family = { +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 9, 0)) .id = GENL_ID_GENERATE, /* Auto generate ID */ +#endif .name = NSS_NLIPSEC_FAMILY, /* Family name string */ .hdrsize = sizeof(struct nss_nlipsec_rule),/* NSS NETLINK IPsec rule */ .version = NSS_NL_VER, /* Set it to NSS_NL version */ @@ -83,13 +132,10 @@ static struct genl_family nss_nlipsec_fa .netnsok = true, .pre_doit = NULL, .post_doit = NULL, -}; - -/* - * Multicast group for sending message status & events - */ -static const struct genl_multicast_group nss_nlipsec_mcgrp[] = { - {.name = NSS_NLIPSEC_MCAST_GRP}, + .ops = nss_nlipsec_ops, + .n_ops = ARRAY_SIZE(nss_nlipsec_ops), + .mcgrps = nss_nlipsec_mcgrp, + .n_mcgrps = ARRAY_SIZE(nss_nlipsec_mcgrp) }; /* @@ -501,7 +547,7 @@ static int nss_nlipsec_op_add_sa(struct sa_data->cmn.keys.auth_key = sa_rule->auth_key; sa_data->cmn.keys.nonce = sa_rule->nonce; - error = nss_ipsecmgr_sa_add_sync(dev, &sa_rule->tuple, sa_data, &if_num); + error = nss_ipsecmgr_sa_add(dev, &sa_rule->tuple, sa_data, &if_num); if (error) { nss_nl_error("%d: Failed to add SA for net device(%s), error:%d\n", pid, nl_rule->ifname, error); goto free_dev; @@ -579,102 +625,73 @@ static int nss_nlipsec_op_delete_sa(stru * nss_nlipsec_op_add_flow() * Add a flow */ -static int nss_nlipsec_op_add_flow(struct sk_buff *skb, struct genl_info *info) -{ - struct nss_ipsecmgr_flow_tuple *flow_tuple; - struct nss_ipsecmgr_sa_tuple *sa_tuple; - struct nss_nlipsec_rule *nl_rule; - struct net_device *dev; - uint32_t pid; - int error = 0; - - nl_rule = nss_nlipsec_get_rule(info, NSS_NLIPSEC_CMD_ADD_FLOW, &dev); - if (!nl_rule) { - nss_nl_error("Failed to extract SA data\n"); - return -EINVAL; - } - - pid = nl_rule->cm.pid; - nss_nl_error("%d: device(%s)", pid, dev->name); - - flow_tuple = &nl_rule->rule.flow.tuple; - sa_tuple = &nl_rule->rule.flow.sa; - - error = nss_ipsecmgr_flow_add_sync(dev, flow_tuple, sa_tuple); - if (error) { - nss_nl_error("%d: Failed to add subnet for net_device(%s)", pid, nl_rule->ifname); - } - - /* - * dev_put for dev_get done on nss_nlipsec_get_rule - */ - dev_put(dev); - return error; -} +// static int nss_nlipsec_op_add_flow(struct sk_buff *skb, struct genl_info *info) +// { +// struct nss_ipsecmgr_flow_tuple *flow_tuple; +// struct nss_ipsecmgr_sa_tuple *sa_tuple; +// struct nss_nlipsec_rule *nl_rule; +// struct net_device *dev; +// uint32_t pid; +// int error = 0; +// +// nl_rule = nss_nlipsec_get_rule(info, NSS_NLIPSEC_CMD_ADD_FLOW, &dev); +// if (!nl_rule) { +// nss_nl_error("Failed to extract SA data\n"); +// return -EINVAL; +// } +// +// pid = nl_rule->cm.pid; +// nss_nl_error("%d: device(%s)", pid, dev->name); +// +// flow_tuple = &nl_rule->rule.flow.tuple; +// sa_tuple = &nl_rule->rule.flow.sa; +// +// //struct nss_ipsecmgr_ref *nss_ipsecmgr_flow_alloc(struct nss_ipsecmgr_priv *priv, struct nss_ipsecmgr_key *key) +// error = nss_ipsecmgr_flow_add_sync(dev, flow_tuple, sa_tuple); +// if (error) { +// nss_nl_error("%d: Failed to add subnet for net_device(%s)", pid, nl_rule->ifname); +// } +// +// /* +// * dev_put for dev_get done on nss_nlipsec_get_rule +// */ +// dev_put(dev); +// return error; +// } /* * nss_nlipsec_op_delete_flow() * Delete a flow */ -static int nss_nlipsec_op_delete_flow(struct sk_buff *skb, struct genl_info *info) -{ - struct nss_ipsecmgr_flow_tuple *flow_tuple; - struct nss_ipsecmgr_sa_tuple *sa_tuple; - struct nss_nlipsec_rule *nl_rule; - struct net_device *dev; - uint32_t pid; - int error = 0; - - nl_rule = nss_nlipsec_get_rule(info, NSS_NLIPSEC_CMD_DEL_FLOW, &dev); - if (!nl_rule) { - nss_nl_error("Failed to extract SA data\n"); - return -EINVAL; - } - - pid = nl_rule->cm.pid; - nss_nl_error("%d: device(%s)", pid, dev->name); - - flow_tuple = &nl_rule->rule.flow.tuple; - sa_tuple = &nl_rule->rule.flow.sa; - - nss_ipsecmgr_flow_del(dev, flow_tuple, sa_tuple); - - /* - * dev_put for dev_get done on nss_nlipsec_get_rule - */ - dev_put(dev); - return error; -} - -/* - * Operation table called by the generic netlink layer based on the command - */ -static struct genl_ops nss_nlipsec_ops[] = { - { /* Create tunnel */ - .cmd = NSS_NLIPSEC_CMD_ADD_TUNNEL, - .doit = nss_nlipsec_op_create_tunnel, - }, - { /* Destroy tunnel */ - .cmd = NSS_NLIPSEC_CMD_DEL_TUNNEL, - .doit = nss_nlipsec_op_destroy_tunnel, - }, - { /* Add Security Association */ - .cmd = NSS_NLIPSEC_CMD_ADD_SA, - .doit = nss_nlipsec_op_add_sa, - }, - { /* Delete Security Association */ - .cmd = NSS_NLIPSEC_CMD_DEL_SA, - .doit = nss_nlipsec_op_delete_sa, - }, - { /* Add flow */ - .cmd = NSS_NLIPSEC_CMD_ADD_FLOW, - .doit = nss_nlipsec_op_add_flow, - }, - { /* Delete flow */ - .cmd = NSS_NLIPSEC_CMD_DEL_FLOW, - .doit = nss_nlipsec_op_delete_flow, - }, -}; +// static int nss_nlipsec_op_delete_flow(struct sk_buff *skb, struct genl_info *info) +// { +// struct nss_ipsecmgr_flow_tuple *flow_tuple; +// struct nss_ipsecmgr_sa_tuple *sa_tuple; +// struct nss_nlipsec_rule *nl_rule; +// struct net_device *dev; +// uint32_t pid; +// int error = 0; +// +// nl_rule = nss_nlipsec_get_rule(info, NSS_NLIPSEC_CMD_DEL_FLOW, &dev); +// if (!nl_rule) { +// nss_nl_error("Failed to extract SA data\n"); +// return -EINVAL; +// } +// +// pid = nl_rule->cm.pid; +// nss_nl_error("%d: device(%s)", pid, dev->name); +// +// flow_tuple = &nl_rule->rule.flow.tuple; +// sa_tuple = &nl_rule->rule.flow.sa; +// +// nss_ipsecmgr_flow_del(dev, flow_tuple, sa_tuple); +// +// /* +// * dev_put for dev_get done on nss_nlipsec_get_rule +// */ +// dev_put(dev); +// return error; +// } /* * nss_nlipsec_init() @@ -700,7 +717,7 @@ bool nss_nlipsec_init(void) /* * Register with the family */ - error = genl_register_family_with_ops_groups(&nss_nlipsec_family, nss_nlipsec_ops, nss_nlipsec_mcgrp); + error = genl_register_family(&nss_nlipsec_family); if (error != 0) { nss_nl_info_always("Error: unable to register IPsec family\n"); return false; --- a/netlink/nss_nlipv4.c +++ b/netlink/nss_nlipv4.c @@ -71,20 +71,6 @@ static int nss_nlipv4_ops_destroy_rule(s static int nss_nlipv4_process_notify(struct notifier_block *nb, unsigned long val, void *data); /* - * IPv4 family definition - */ -static struct genl_family nss_nlipv4_family = { - .id = GENL_ID_GENERATE, /* Auto generate ID */ - .name = NSS_NLIPV4_FAMILY, /* family name string */ - .hdrsize = sizeof(struct nss_nlipv4_rule), /* NSS NETLINK IPv4 rule */ - .version = NSS_NL_VER, /* Set it to NSS_NLIPv4 version */ - .maxattr = NSS_IPV4_MAX_MSG_TYPES, /* maximum commands supported */ - .netnsok = true, - .pre_doit = NULL, - .post_doit = NULL, -}; - -/* * multicast group for sending message status & events */ static const struct genl_multicast_group nss_nlipv4_mcgrp[] = { @@ -100,6 +86,26 @@ static struct genl_ops nss_nlipv4_ops[] }; /* + * IPv4 family definition + */ +static struct genl_family nss_nlipv4_family = { +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 9, 0)) + .id = GENL_ID_GENERATE, /* Auto generate ID */ +#endif + .name = NSS_NLIPV4_FAMILY, /* family name string */ + .hdrsize = sizeof(struct nss_nlipv4_rule), /* NSS NETLINK IPv4 rule */ + .version = NSS_NL_VER, /* Set it to NSS_NLIPv4 version */ + .maxattr = NSS_IPV4_MAX_MSG_TYPES, /* maximum commands supported */ + .netnsok = true, + .pre_doit = NULL, + .post_doit = NULL, + .ops = nss_nlipv4_ops, + .n_ops = ARRAY_SIZE(nss_nlipv4_ops), + .mcgrps = nss_nlipv4_mcgrp, + .n_mcgrps = ARRAY_SIZE(nss_nlipv4_mcgrp) +}; + +/* * statistics call back handler for ipv4 from NSS */ static struct notifier_block nss_ipv4_stats_notifier_nb = { @@ -915,7 +921,7 @@ bool nss_nlipv4_init(void) /* * register NETLINK ops with the family */ - error = genl_register_family_with_ops_groups(&nss_nlipv4_family, nss_nlipv4_ops, nss_nlipv4_mcgrp); + error = genl_register_family(&nss_nlipv4_family); if (error != 0) { nss_nl_info_always("Error: unable to register IPv4 family\n"); return false; --- a/netlink/nss_nlipv4_reasm.c +++ b/netlink/nss_nlipv4_reasm.c @@ -46,20 +46,6 @@ static int nss_nlipv4_reasm_ops_get_stat static int nss_nlipv4_reasm_process_notify(struct notifier_block *nb, unsigned long val, void *data); /* - * ipv4_reasm family definition - */ -static struct genl_family nss_nlipv4_reasm_family = { - .id = GENL_ID_GENERATE, /* Auto generate ID */ - .name = NSS_NLIPV4_REASM_FAMILY, /* family name string */ - .hdrsize = sizeof(struct nss_ipv4_reasm_stats_notification), /* NSS NETLINK ipv4_reasm stats */ - .version = NSS_NL_VER, /* Set it to NSS_NLIPV4_REASM version */ - .maxattr = NSS_STATS_EVENT_MAX, /* maximum commands supported */ - .netnsok = true, - .pre_doit = NULL, - .post_doit = NULL, -}; - -/* * multicast group for sending message status & events */ static const struct genl_multicast_group nss_nlipv4_reasm_mcgrp[] = { @@ -74,6 +60,26 @@ static struct genl_ops nss_nlipv4_reasm_ }; /* + * ipv4_reasm family definition + */ +static struct genl_family nss_nlipv4_reasm_family = { +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 9, 0)) + .id = GENL_ID_GENERATE, /* Auto generate ID */ +#endif + .name = NSS_NLIPV4_REASM_FAMILY, /* family name string */ + .hdrsize = sizeof(struct nss_ipv4_reasm_stats_notification), /* NSS NETLINK ipv4_reasm stats */ + .version = NSS_NL_VER, /* Set it to NSS_NLIPV4_REASM version */ + .maxattr = NSS_STATS_EVENT_MAX, /* maximum commands supported */ + .netnsok = true, + .pre_doit = NULL, + .post_doit = NULL, + .ops = nss_nlipv4_reasm_ops, + .n_ops = ARRAY_SIZE(nss_nlipv4_reasm_ops), + .mcgrps = nss_nlipv4_reasm_mcgrp, + .n_mcgrps = ARRAY_SIZE(nss_nlipv4_reasm_mcgrp) +}; + +/* * stats call back handler for ipv4_reasm from NSS */ static struct notifier_block nss_ipv4_reasm_stats_notifier_nb = { @@ -125,7 +131,7 @@ bool nss_nlipv4_reasm_init(void) /* * register NETLINK ops with the family */ - error = genl_register_family_with_ops_groups(&nss_nlipv4_reasm_family, nss_nlipv4_reasm_ops, nss_nlipv4_reasm_mcgrp); + error = genl_register_family(&nss_nlipv4_reasm_family); if (error) { nss_nl_info_always("Error: unable to register ipv4_reasm family\n"); return false; --- a/netlink/nss_nlipv6.c +++ b/netlink/nss_nlipv6.c @@ -79,20 +79,6 @@ static int nss_nlipv6_ops_destroy_rule(s static int nss_nlipv6_process_notify(struct notifier_block *nb, unsigned long val, void *data); /* - * IPV6 family definition - */ -static struct genl_family nss_nlipv6_family = { - .id = GENL_ID_GENERATE, /* Auto generate ID */ - .name = NSS_NLIPV6_FAMILY, /* family name string */ - .hdrsize = sizeof(struct nss_nlipv6_rule), /* NSS NETLINK IPV6 rule */ - .version = NSS_NL_VER, /* Set it to NSS_NLIPV6 version */ - .maxattr = NSS_IPV6_MAX_MSG_TYPES, /* maximum commands supported */ - .netnsok = true, - .pre_doit = NULL, - .post_doit = NULL, -}; - -/* * multicast group for sending message status & events */ static struct genl_multicast_group nss_nlipv6_mcgrp[] = { @@ -108,6 +94,26 @@ static struct genl_ops nss_nlipv6_ops[] }; /* + * IPV6 family definition + */ +static struct genl_family nss_nlipv6_family = { +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 9, 0)) + .id = GENL_ID_GENERATE, /* Auto generate ID */ +#endif + .name = NSS_NLIPV6_FAMILY, /* family name string */ + .hdrsize = sizeof(struct nss_nlipv6_rule), /* NSS NETLINK IPV6 rule */ + .version = NSS_NL_VER, /* Set it to NSS_NLIPV6 version */ + .maxattr = NSS_IPV6_MAX_MSG_TYPES, /* maximum commands supported */ + .netnsok = true, + .pre_doit = NULL, + .post_doit = NULL, + .ops = nss_nlipv6_ops, + .n_ops = ARRAY_SIZE(nss_nlipv6_ops), + .mcgrps = nss_nlipv6_mcgrp, + .n_mcgrps = ARRAY_SIZE(nss_nlipv6_mcgrp) +}; + +/* * statistics call back handler for ipv6 from NSS */ static struct notifier_block nss_ipv6_stats_notifier_nb = { @@ -131,7 +137,11 @@ static struct neighbour *nss_nlipv6_get_ IPV6_ADDR_TO_IN6_ADDR(daddr, dst_addr); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0)) rt = rt6_lookup(&init_net, &daddr, NULL, 0, 0); +#else + rt = rt6_lookup(&init_net, &daddr, NULL, 0, NULL, 0); +#endif if (!rt) { return NULL; } @@ -916,7 +926,7 @@ bool nss_nlipv6_init(void) /* * register NETLINK ops with the family */ - error = genl_register_family_with_ops_groups(&nss_nlipv6_family, nss_nlipv6_ops, nss_nlipv6_mcgrp); + error = genl_register_family(&nss_nlipv6_family); if (error != 0) { nss_nl_info_always("Error: unable to register IPV6 family\n"); return false; --- a/netlink/nss_nlipv6_reasm.c +++ b/netlink/nss_nlipv6_reasm.c @@ -46,20 +46,6 @@ static int nss_nlipv6_reasm_ops_get_stat static int nss_nlipv6_reasm_process_notify(struct notifier_block *nb, unsigned long val, void *data); /* - * ipv6_reasm family definition - */ -static struct genl_family nss_nlipv6_reasm_family = { - .id = GENL_ID_GENERATE, /* Auto generate ID */ - .name = NSS_NLIPV6_REASM_FAMILY, /* family name string */ - .hdrsize = sizeof(struct nss_ipv6_reasm_stats_notification), /* NSS NETLINK ipv6_reasm stats */ - .version = NSS_NL_VER, /* Set it to NSS_NLIPV6_REASM version */ - .maxattr = NSS_STATS_EVENT_MAX, /* maximum commands supported */ - .netnsok = true, - .pre_doit = NULL, - .post_doit = NULL, -}; - -/* * multicast group for sending message status & events */ static const struct genl_multicast_group nss_nlipv6_reasm_mcgrp[] = { @@ -74,6 +60,26 @@ static struct genl_ops nss_nlipv6_reasm_ }; /* + * ipv6_reasm family definition + */ +static struct genl_family nss_nlipv6_reasm_family = { +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 9, 0)) + .id = GENL_ID_GENERATE, /* Auto generate ID */ +#endif + .name = NSS_NLIPV6_REASM_FAMILY, /* family name string */ + .hdrsize = sizeof(struct nss_ipv6_reasm_stats_notification), /* NSS NETLINK ipv6_reasm stats */ + .version = NSS_NL_VER, /* Set it to NSS_NLIPV6_REASM version */ + .maxattr = NSS_STATS_EVENT_MAX, /* maximum commands supported */ + .netnsok = true, + .pre_doit = NULL, + .post_doit = NULL, + .ops = nss_nlipv6_reasm_ops, + .n_ops = ARRAY_SIZE(nss_nlipv6_reasm_ops), + .mcgrps = nss_nlipv6_reasm_mcgrp, + .n_mcgrps = ARRAY_SIZE(nss_nlipv6_reasm_mcgrp) +}; + +/* * stats call back handler for ipv6_reasm from NSS */ static struct notifier_block nss_ipv6_reasm_stats_notifier_nb = { @@ -125,7 +131,7 @@ bool nss_nlipv6_reasm_init(void) /* * register NETLINK ops with the family */ - error = genl_register_family_with_ops_groups(&nss_nlipv6_reasm_family, nss_nlipv6_reasm_ops, nss_nlipv6_reasm_mcgrp); + error = genl_register_family(&nss_nlipv6_reasm_family); if (error) { nss_nl_info_always("Error: unable to register ipv6_reasm family\n"); return false; --- a/netlink/nss_nll2tpv2.c +++ b/netlink/nss_nll2tpv2.c @@ -47,20 +47,6 @@ static int nss_nll2tpv2_ops_get_stats(st static int nss_nll2tpv2_process_notify(struct notifier_block *nb, unsigned long val, void *data); /* - * l2tpv2 family definition - */ -static struct genl_family nss_nll2tpv2_family = { - .id = GENL_ID_GENERATE, /* Auto generate ID */ - .name = NSS_NLL2TPV2_FAMILY, /* family name string */ - .hdrsize = sizeof(struct nss_l2tpv2_stats_notification), /* NSS NETLINK l2tpv2 stats */ - .version = NSS_NL_VER, /* Set it to NSS_NLL2TPV2 version */ - .maxattr = NSS_STATS_EVENT_MAX, /* maximum commands supported */ - .netnsok = true, - .pre_doit = NULL, - .post_doit = NULL, -}; - -/* * multicast group for sending message status & events */ static const struct genl_multicast_group nss_nll2tpv2_mcgrp[] = { @@ -75,6 +61,26 @@ static struct genl_ops nss_nll2tpv2_ops[ }; /* + * l2tpv2 family definition + */ +static struct genl_family nss_nll2tpv2_family = { +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 9, 0)) + .id = GENL_ID_GENERATE, /* Auto generate ID */ +#endif + .name = NSS_NLL2TPV2_FAMILY, /* family name string */ + .hdrsize = sizeof(struct nss_l2tpv2_stats_notification), /* NSS NETLINK l2tpv2 stats */ + .version = NSS_NL_VER, /* Set it to NSS_NLL2TPV2 version */ + .maxattr = NSS_STATS_EVENT_MAX, /* maximum commands supported */ + .netnsok = true, + .pre_doit = NULL, + .post_doit = NULL, + .ops = nss_nll2tpv2_ops, + .n_ops = ARRAY_SIZE(nss_nll2tpv2_ops), + .mcgrps = nss_nll2tpv2_mcgrp, + .n_mcgrps = ARRAY_SIZE(nss_nll2tpv2_mcgrp) +}; + +/* * device call back handler for l2tpv2 from NSS */ static struct notifier_block nss_l2tpv2_stats_notifier_nb = { @@ -126,7 +132,7 @@ bool nss_nll2tpv2_init(void) /* * register NETLINK ops with the family */ - error = genl_register_family_with_ops_groups(&nss_nll2tpv2_family, nss_nll2tpv2_ops, nss_nll2tpv2_mcgrp); + error = genl_register_family(&nss_nll2tpv2_family); if (error) { nss_nl_info_always("Error: unable to register l2tpv2 family\n"); return false; --- a/netlink/nss_nllso_rx.c +++ b/netlink/nss_nllso_rx.c @@ -47,20 +47,6 @@ static int nss_nllso_rx_ops_get_stats(st static int nss_nllso_rx_process_notify(struct notifier_block *nb, unsigned long val, void *data); /* - * lso_rx family definition - */ -static struct genl_family nss_nllso_rx_family = { - .id = GENL_ID_GENERATE, /* Auto generate ID */ - .name = NSS_NLLSO_RX_FAMILY, /* family name string */ - .hdrsize = sizeof(struct nss_lso_rx_stats_notification), /* NSS NETLINK lso_rx stats */ - .version = NSS_NL_VER, /* Set it to NSS_NLLSO_RX version */ - .maxattr = NSS_STATS_EVENT_MAX, /* maximum commands supported */ - .netnsok = true, - .pre_doit = NULL, - .post_doit = NULL, -}; - -/* * multicast group for sending message status & events */ static const struct genl_multicast_group nss_nllso_rx_mcgrp[] = { @@ -75,6 +61,26 @@ static struct genl_ops nss_nllso_rx_ops[ }; /* + * lso_rx family definition + */ +static struct genl_family nss_nllso_rx_family = { +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 9, 0)) + .id = GENL_ID_GENERATE, /* Auto generate ID */ +#endif + .name = NSS_NLLSO_RX_FAMILY, /* family name string */ + .hdrsize = sizeof(struct nss_lso_rx_stats_notification), /* NSS NETLINK lso_rx stats */ + .version = NSS_NL_VER, /* Set it to NSS_NLLSO_RX version */ + .maxattr = NSS_STATS_EVENT_MAX, /* maximum commands supported */ + .netnsok = true, + .pre_doit = NULL, + .post_doit = NULL, + .ops = nss_nllso_rx_ops, + .n_ops = ARRAY_SIZE(nss_nllso_rx_ops), + .mcgrps = nss_nllso_rx_mcgrp, + .n_mcgrps = ARRAY_SIZE(nss_nllso_rx_mcgrp) +}; + +/* * device call back handler for lso_rx from NSS */ static struct notifier_block nss_lso_rx_stats_notifier_nb = { @@ -126,7 +132,7 @@ bool nss_nllso_rx_init(void) /* * register NETLINK ops with the family */ - error = genl_register_family_with_ops_groups(&nss_nllso_rx_family, nss_nllso_rx_ops, nss_nllso_rx_mcgrp); + error = genl_register_family(&nss_nllso_rx_family); if (error) { nss_nl_info_always("Error: unable to register lso_rx family\n"); return false; --- a/netlink/nss_nlmap_t.c +++ b/netlink/nss_nlmap_t.c @@ -47,20 +47,6 @@ static int nss_nlmap_t_ops_get_stats(str static int nss_nlmap_t_process_notify(struct notifier_block *nb, unsigned long val, void *data); /* - * map_t family definition - */ -static struct genl_family nss_nlmap_t_family = { - .id = GENL_ID_GENERATE, /* Auto generate ID */ - .name = NSS_NLMAP_T_FAMILY, /* family name string */ - .hdrsize = sizeof(struct nss_map_t_stats_notification), /* NSS NETLINK map_t stats */ - .version = NSS_NL_VER, /* Set it to NSS_NLMAP_T version */ - .maxattr = NSS_STATS_EVENT_MAX, /* maximum commands supported */ - .netnsok = true, - .pre_doit = NULL, - .post_doit = NULL, -}; - -/* * multicast group for sending message status & events */ static const struct genl_multicast_group nss_nlmap_t_mcgrp[] = { @@ -75,6 +61,26 @@ static struct genl_ops nss_nlmap_t_ops[] }; /* + * map_t family definition + */ +static struct genl_family nss_nlmap_t_family = { +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 9, 0)) + .id = GENL_ID_GENERATE, /* Auto generate ID */ +#endif + .name = NSS_NLMAP_T_FAMILY, /* family name string */ + .hdrsize = sizeof(struct nss_map_t_stats_notification), /* NSS NETLINK map_t stats */ + .version = NSS_NL_VER, /* Set it to NSS_NLMAP_T version */ + .maxattr = NSS_STATS_EVENT_MAX, /* maximum commands supported */ + .netnsok = true, + .pre_doit = NULL, + .post_doit = NULL, + .ops = nss_nlmap_t_ops, + .n_ops = ARRAY_SIZE(nss_nlmap_t_ops), + .mcgrps = nss_nlmap_t_mcgrp, + .n_mcgrps = ARRAY_SIZE(nss_nlmap_t_mcgrp) +}; + +/* * device call back handler for map_t from NSS */ static struct notifier_block nss_map_t_stats_notifier_nb = { @@ -126,7 +132,7 @@ bool nss_nlmap_t_init(void) /* * register NETLINK ops with the family */ - error = genl_register_family_with_ops_groups(&nss_nlmap_t_family, nss_nlmap_t_ops, nss_nlmap_t_mcgrp); + error = genl_register_family(&nss_nlmap_t_family); if (error) { nss_nl_info_always("Error: unable to register map_t family\n"); return false; --- a/netlink/nss_nln2h.c +++ b/netlink/nss_nln2h.c @@ -46,20 +46,6 @@ static int nss_nln2h_ops_get_stats(struc static int nss_nln2h_process_notify(struct notifier_block *nb, unsigned long val, void *data); /* - * n2h family definition - */ -static struct genl_family nss_nln2h_family = { - .id = GENL_ID_GENERATE, /* Auto generate ID */ - .name = NSS_NLN2H_FAMILY, /* family name string */ - .hdrsize = sizeof(struct nss_n2h_stats_notification), /* NSS NETLINK n2h stats */ - .version = NSS_NL_VER, /* Set it to NSS_NLN2H version */ - .maxattr = NSS_STATS_EVENT_MAX, /* maximum commands supported */ - .netnsok = true, - .pre_doit = NULL, - .post_doit = NULL, -}; - -/* * multicast group for sending message status & events */ static const struct genl_multicast_group nss_nln2h_mcgrp[] = { @@ -74,6 +60,26 @@ static struct genl_ops nss_nln2h_ops[] = }; /* + * n2h family definition + */ +static struct genl_family nss_nln2h_family = { +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 9, 0)) + .id = GENL_ID_GENERATE, /* Auto generate ID */ +#endif + .name = NSS_NLN2H_FAMILY, /* family name string */ + .hdrsize = sizeof(struct nss_n2h_stats_notification), /* NSS NETLINK n2h stats */ + .version = NSS_NL_VER, /* Set it to NSS_NLN2H version */ + .maxattr = NSS_STATS_EVENT_MAX, /* maximum commands supported */ + .netnsok = true, + .pre_doit = NULL, + .post_doit = NULL, + .ops = nss_nln2h_ops, + .n_ops = ARRAY_SIZE(nss_nln2h_ops), + .mcgrps = nss_nln2h_mcgrp, + .n_mcgrps = ARRAY_SIZE(nss_nln2h_mcgrp) +}; + +/* * stats call back handler for n2h from NSS */ static struct notifier_block nss_n2h_stats_notifier_nb = { @@ -125,7 +131,7 @@ bool nss_nln2h_init(void) /* * register NETLINK ops with the family */ - error = genl_register_family_with_ops_groups(&nss_nln2h_family, nss_nln2h_ops, nss_nln2h_mcgrp); + error = genl_register_family(&nss_nln2h_family); if (error) { nss_nl_info_always("Error: unable to register n2h family\n"); return false; --- a/netlink/nss_nloam.c +++ b/netlink/nss_nloam.c @@ -1,6 +1,6 @@ /* ************************************************************************** - * Copyright (c) 2016,2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2016,2018, 2020, The Linux Foundation. All rights reserved. * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the * above copyright notice and this permission notice appear in all copies. @@ -82,11 +82,25 @@ struct nss_nloam_msg_map global_nloam_ms }, }; +static struct genl_multicast_group nss_nloam_mcgrp[] = { + {.name = NSS_NLOAM_MCAST_GRP}, +}; + +/* + * operation table called by the generic netlink layer based on the command + */ +static struct genl_ops nss_nloam_ops[] = { + {.cmd = NSS_NLOAM_CMD_NONE, .doit = nss_nloam_op_none,}, + {.cmd = NSS_NLOAM_CMD_GET_REQ, .doit = nss_nloam_op_get_req,}, +}; + /* * OAM family definition */ static struct genl_family nss_nloam_family = { +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 9, 0)) .id = GENL_ID_GENERATE, /* Auto generate ID */ +#endif .name = NSS_NLOAM_FAMILY, /* family name string */ .hdrsize = sizeof(struct nss_nloam_rule), /* NLOAM msg size */ .version = NSS_NL_VER, /* nss netlink version */ @@ -94,18 +108,10 @@ static struct genl_family nss_nloam_fami .netnsok = false, .pre_doit = NULL, .post_doit = NULL, -}; - -static struct genl_multicast_group nss_nloam_mcgrp[] = { - {.name = NSS_NLOAM_MCAST_GRP}, -}; - -/* - * operation table called by the generic netlink layer based on the command - */ -static struct genl_ops nss_nloam_ops[] = { - {.cmd = NSS_NLOAM_CMD_NONE, .doit = nss_nloam_op_none,}, - {.cmd = NSS_NLOAM_CMD_GET_REQ, .doit = nss_nloam_op_get_req,}, + .ops = nss_nloam_ops, + .n_ops = ARRAY_SIZE(nss_nloam_ops), + .mcgrps = nss_nloam_mcgrp, + .n_mcgrps = ARRAY_SIZE(nss_nloam_mcgrp) }; #define NSS_NLOAM_OPS_SZ ARRAY_SIZE(nss_nloam_ops) @@ -340,7 +346,7 @@ bool nss_nloam_init(void) /* * register with the family */ - error = genl_register_family_with_ops_groups(&nss_nloam_family, nss_nloam_ops, nss_nloam_mcgrp); + error = genl_register_family(&nss_nloam_family); if (error != 0) { nss_nl_info_always("unable to register OAM family\n"); return false; --- a/netlink/nss_nlpppoe.c +++ b/netlink/nss_nlpppoe.c @@ -47,20 +47,6 @@ static int nss_nlpppoe_ops_get_stats(str static int nss_nlpppoe_process_notify(struct notifier_block *nb, unsigned long val, void *data); /* - * pppoe family definition - */ -static struct genl_family nss_nlpppoe_family = { - .id = GENL_ID_GENERATE, /* Auto generate ID */ - .name = NSS_NLPPPOE_FAMILY, /* family name string */ - .hdrsize = sizeof(struct nss_pppoe_stats_notification), /* NSS NETLINK pppoe stats */ - .version = NSS_NL_VER, /* Set it to NSS_NLPPPOE version */ - .maxattr = NSS_STATS_EVENT_MAX, /* maximum commands supported */ - .netnsok = true, - .pre_doit = NULL, - .post_doit = NULL, -}; - -/* * multicast group for sending message status & events */ static const struct genl_multicast_group nss_nlpppoe_mcgrp[] = { @@ -75,6 +61,26 @@ static struct genl_ops nss_nlpppoe_ops[] }; /* + * pppoe family definition + */ +static struct genl_family nss_nlpppoe_family = { +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 9, 0)) + .id = GENL_ID_GENERATE, /* Auto generate ID */ +#endif + .name = NSS_NLPPPOE_FAMILY, /* family name string */ + .hdrsize = sizeof(struct nss_pppoe_stats_notification), /* NSS NETLINK pppoe stats */ + .version = NSS_NL_VER, /* Set it to NSS_NLPPPOE version */ + .maxattr = NSS_STATS_EVENT_MAX, /* maximum commands supported */ + .netnsok = true, + .pre_doit = NULL, + .post_doit = NULL, + .ops = nss_nlpppoe_ops, + .n_ops = ARRAY_SIZE(nss_nlpppoe_ops), + .mcgrps = nss_nlpppoe_mcgrp, + .n_mcgrps = ARRAY_SIZE(nss_nlpppoe_mcgrp) +}; + +/* * device call back handler for pppoe from NSS */ static struct notifier_block nss_pppoe_stats_notifier_nb = { @@ -126,7 +132,7 @@ bool nss_nlpppoe_init(void) /* * register NETLINK ops with the family */ - error = genl_register_family_with_ops_groups(&nss_nlpppoe_family, nss_nlpppoe_ops, nss_nlpppoe_mcgrp); + error = genl_register_family(&nss_nlpppoe_family); if (error) { nss_nl_info_always("Error: unable to register pppoe family\n"); return false; --- a/netlink/nss_nlpptp.c +++ b/netlink/nss_nlpptp.c @@ -47,20 +47,6 @@ static int nss_nlpptp_ops_get_stats(stru static int nss_nlpptp_process_notify(struct notifier_block *nb, unsigned long val, void *data); /* - * pptp family definition - */ -static struct genl_family nss_nlpptp_family = { - .id = GENL_ID_GENERATE, /* Auto generate ID */ - .name = NSS_NLPPTP_FAMILY, /* family name string */ - .hdrsize = sizeof(struct nss_pptp_stats_notification), /* NSS NETLINK pptp stats */ - .version = NSS_NL_VER, /* Set it to NSS_NLPPTP version */ - .maxattr = NSS_STATS_EVENT_MAX, /* maximum commands supported */ - .netnsok = true, - .pre_doit = NULL, - .post_doit = NULL, -}; - -/* * multicast group for sending message status & events */ static const struct genl_multicast_group nss_nlpptp_mcgrp[] = { @@ -75,6 +61,26 @@ static struct genl_ops nss_nlpptp_ops[] }; /* + * pptp family definition + */ +static struct genl_family nss_nlpptp_family = { +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 9, 0)) + .id = GENL_ID_GENERATE, /* Auto generate ID */ +#endif + .name = NSS_NLPPTP_FAMILY, /* family name string */ + .hdrsize = sizeof(struct nss_pptp_stats_notification), /* NSS NETLINK pptp stats */ + .version = NSS_NL_VER, /* Set it to NSS_NLPPTP version */ + .maxattr = NSS_STATS_EVENT_MAX, /* maximum commands supported */ + .netnsok = true, + .pre_doit = NULL, + .post_doit = NULL, + .ops = nss_nlpptp_ops, + .n_ops = ARRAY_SIZE(nss_nlpptp_ops), + .mcgrps = nss_nlpptp_mcgrp, + .n_mcgrps = ARRAY_SIZE(nss_nlpptp_mcgrp) +}; + +/* * device call back handler for pptp from NSS */ static struct notifier_block nss_pptp_stats_notifier_nb = { @@ -126,7 +132,7 @@ bool nss_nlpptp_init(void) /* * register NETLINK ops with the family */ - error = genl_register_family_with_ops_groups(&nss_nlpptp_family, nss_nlpptp_ops, nss_nlpptp_mcgrp); + error = genl_register_family(&nss_nlpptp_family); if (error) { nss_nl_info_always("Error: unable to register pptp family\n"); return false; --- a/netlink/nss_nlwifili.c +++ b/netlink/nss_nlwifili.c @@ -47,20 +47,6 @@ static int nss_nlwifili_ops_get_stats(st static int nss_nlwifili_process_notify(struct notifier_block *nb, unsigned long val, void *data); /* - * wifili family definition - */ -static struct genl_family nss_nlwifili_family = { - .id = GENL_ID_GENERATE, /* Auto generate ID */ - .name = NSS_NLWIFILI_FAMILY, /* family name string */ - .hdrsize = sizeof(struct nss_wifili_stats_notification), /* NSS NETLINK wifili stats */ - .version = NSS_NL_VER, /* Set it to NSS_NLWIFILI version */ - .maxattr = NSS_STATS_EVENT_MAX, /* maximum commands supported */ - .netnsok = true, - .pre_doit = NULL, - .post_doit = NULL, -}; - -/* * multicast group for sending message status & events */ static const struct genl_multicast_group nss_nlwifili_mcgrp[] = { @@ -75,6 +61,26 @@ static struct genl_ops nss_nlwifili_ops[ }; /* + * wifili family definition + */ +static struct genl_family nss_nlwifili_family = { +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 9, 0)) + .id = GENL_ID_GENERATE, /* Auto generate ID */ +#endif + .name = NSS_NLWIFILI_FAMILY, /* family name string */ + .hdrsize = sizeof(struct nss_wifili_stats_notification), /* NSS NETLINK wifili stats */ + .version = NSS_NL_VER, /* Set it to NSS_NLWIFILI version */ + .maxattr = NSS_STATS_EVENT_MAX, /* maximum commands supported */ + .netnsok = true, + .pre_doit = NULL, + .post_doit = NULL, + .ops = nss_nlwifili_ops, + .n_ops = ARRAY_SIZE(nss_nlwifili_ops), + .mcgrps = nss_nlwifili_mcgrp, + .n_mcgrps = ARRAY_SIZE(nss_nlwifili_mcgrp) +}; + +/* * device call back handler for wifili from NSS */ static struct notifier_block nss_wifili_stats_notifier_nb = { @@ -126,7 +132,7 @@ bool nss_nlwifili_init(void) /* * register NETLINK ops with the family */ - error = genl_register_family_with_ops_groups(&nss_nlwifili_family, nss_nlwifili_ops, nss_nlwifili_mcgrp); + error = genl_register_family(&nss_nlwifili_family); if (error) { nss_nl_info_always("Error: unable to register wifili family\n"); return false; --- a/netlink/nss_nlcapwap.c +++ b/netlink/nss_nlcapwap.c @@ -36,7 +36,6 @@ #include #include #include -#include "nss_crypto_defines.h" #include "nss_nl.h" #include "nss_nlcapwap_if.h" #include "nss_nlcapwap.h" @@ -1510,7 +1509,7 @@ bool nss_nlcapwap_init(void) /* * register NETLINK ops with the family */ - err = genl_register_family_with_ops_groups(&nss_nlcapwap_family, nss_nlcapwap_cmd_ops, nss_nlcapwap_family_mcgrp); + err = genl_register_family(&nss_nlcapwap_family); if (err) { nss_nl_info_always("Error: %d unable to register capwap family\n", err); goto free;