Re: [PATCH 18/20] iwlwifi: fix malformed CONFIG_IWLWIFI_PCIE_RTPM default

2018-02-14 Thread Luciano Coelho
On Mon, 2018-02-05 at 02:21 +0100, Ulf Magnusson wrote:
> 'default false' should be 'default n', though they happen to have the
> same effect here, due to undefined symbols ('false' in this case)
> evaluating to n in a tristate sense.
> 
> Remove the default instead of changing it. bool and tristate symbols
> implicitly default to n.
> 
> Discovered with the
> https://github.com/ulfalizer/Kconfiglib/blob/master/examples/list_und
> efined.py
> script.
> 
> Signed-off-by: Ulf Magnusson 
> ---

Thanks, Ulf!

This is applied in our internal tree and will eventually reach the
mainline, following our usual upstreaming process.

--
Cheers,
Luca.


[PATCH] rtl8187: Fix NULL pointer dereference in priv->conf_mutex

2018-02-14 Thread Sudhir Sreedharan
This can be reproduced by bind/unbind the driver multiple times
in AM3517 board.

Analysis revealed that rtl8187_start() was invoked before probe
finishes(ie. before the mutex is initialized).

 INFO: trying to register non-static key.
 the code is fine but needs lockdep annotation.
 turning off the locking correctness validator.
 CPU: 0 PID: 821 Comm: wpa_supplicant Not tainted 4.9.80-dirty #250
 Hardware name: Generic AM3517 (Flattened Device Tree)
 [] (unwind_backtrace) from [] (show_stack+0x10/0x14)
 [] (show_stack) from [] (register_lock_class+0x4f4/0x55c)
 [] (register_lock_class) from [] 
(__lock_acquire+0x74/0x1938)
 [] (__lock_acquire) from [] (lock_acquire+0xfc/0x23c)
 [] (lock_acquire) from [] (mutex_lock_nested+0x50/0x3b0)
 [] (mutex_lock_nested) from [] (rtl8187_start+0x2c/0xd54)
 [] (rtl8187_start) from [] (drv_start+0xa8/0x320)
 [] (drv_start) from [] (ieee80211_do_open+0x2bc/0x8e4)
 [] (ieee80211_do_open) from [] (__dev_open+0xb8/0x120)
 [] (__dev_open) from [] (__dev_change_flags+0x88/0x14c)
 [] (__dev_change_flags) from [] 
(dev_change_flags+0x18/0x48)
 [] (dev_change_flags) from [] (devinet_ioctl+0x738/0x840)
 [] (devinet_ioctl) from [] (sock_ioctl+0x164/0x2f4)
 [] (sock_ioctl) from [] (do_vfs_ioctl+0x8c/0x9d0)
 [] (do_vfs_ioctl) from [] (SyS_ioctl+0x6c/0x7c)
 [] (SyS_ioctl) from [] (ret_fast_syscall+0x0/0x1c)
 Unable to handle kernel NULL pointer dereference at virtual address 
 pgd = cd1ec000
 [] *pgd=8d1de831, *pte=, *ppte=
 Internal error: Oops: 817 [#1] PREEMPT ARM
 Modules linked in:
 CPU: 0 PID: 821 Comm: wpa_supplicant Not tainted 4.9.80-dirty #250
 Hardware name: Generic AM3517 (Flattened Device Tree)
 task: ce73eec0 task.stack: cd1ea000
 PC is at mutex_lock_nested+0xe8/0x3b0
 LR is at mutex_lock_nested+0xd0/0x3b0

Cc: sta...@vger.kernel.org
Signed-off-by: Sudhir Sreedharan 
---
 drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c 
b/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c
index 121b94f..9a1d15b 100644
--- a/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c
+++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c
@@ -1450,6 +1450,7 @@ static int rtl8187_probe(struct usb_interface *intf,
goto err_free_dev;
}
mutex_init(>io_mutex);
+   mutex_init(>conf_mutex);
 
SET_IEEE80211_DEV(dev, >dev);
usb_set_intfdata(intf, dev);
@@ -1625,7 +1626,6 @@ static int rtl8187_probe(struct usb_interface *intf,
printk(KERN_ERR "rtl8187: Cannot register device\n");
goto err_free_dmabuf;
}
-   mutex_init(>conf_mutex);
skb_queue_head_init(>b_tx_status.queue);
 
wiphy_info(dev->wiphy, "hwaddr %pM, %s V%d + %s, rfkill mask %d\n",
-- 
2.6.4



[Crypto v5 07/12] chcr: Key Macro

2018-02-14 Thread Atul Gupta
Define macro for TLS Key context

Signed-off-by: Atul Gupta 
---
 drivers/crypto/chelsio/chcr_algo.h | 42 +
 drivers/crypto/chelsio/chcr_core.h | 55 +-
 2 files changed, 96 insertions(+), 1 deletion(-)

diff --git a/drivers/crypto/chelsio/chcr_algo.h 
b/drivers/crypto/chelsio/chcr_algo.h
index d1673a5..f263cd4 100644
--- a/drivers/crypto/chelsio/chcr_algo.h
+++ b/drivers/crypto/chelsio/chcr_algo.h
@@ -86,6 +86,39 @@
 KEY_CONTEXT_OPAD_PRESENT_M)
 #define KEY_CONTEXT_OPAD_PRESENT_F  KEY_CONTEXT_OPAD_PRESENT_V(1U)
 
+#define TLS_KEYCTX_RXFLIT_CNT_S 24
+#define TLS_KEYCTX_RXFLIT_CNT_V(x) ((x) << TLS_KEYCTX_RXFLIT_CNT_S)
+
+#define TLS_KEYCTX_RXPROT_VER_S 20
+#define TLS_KEYCTX_RXPROT_VER_M 0xf
+#define TLS_KEYCTX_RXPROT_VER_V(x) ((x) << TLS_KEYCTX_RXPROT_VER_S)
+
+#define TLS_KEYCTX_RXCIPH_MODE_S 16
+#define TLS_KEYCTX_RXCIPH_MODE_M 0xf
+#define TLS_KEYCTX_RXCIPH_MODE_V(x) ((x) << TLS_KEYCTX_RXCIPH_MODE_S)
+
+#define TLS_KEYCTX_RXAUTH_MODE_S 12
+#define TLS_KEYCTX_RXAUTH_MODE_M 0xf
+#define TLS_KEYCTX_RXAUTH_MODE_V(x) ((x) << TLS_KEYCTX_RXAUTH_MODE_S)
+
+#define TLS_KEYCTX_RXCIAU_CTRL_S 11
+#define TLS_KEYCTX_RXCIAU_CTRL_V(x) ((x) << TLS_KEYCTX_RXCIAU_CTRL_S)
+
+#define TLS_KEYCTX_RX_SEQCTR_S 9
+#define TLS_KEYCTX_RX_SEQCTR_M 0x3
+#define TLS_KEYCTX_RX_SEQCTR_V(x) ((x) << TLS_KEYCTX_RX_SEQCTR_S)
+
+#define TLS_KEYCTX_RX_VALID_S 8
+#define TLS_KEYCTX_RX_VALID_V(x) ((x) << TLS_KEYCTX_RX_VALID_S)
+
+#define TLS_KEYCTX_RXCK_SIZE_S 3
+#define TLS_KEYCTX_RXCK_SIZE_M 0x7
+#define TLS_KEYCTX_RXCK_SIZE_V(x) ((x) << TLS_KEYCTX_RXCK_SIZE_S)
+
+#define TLS_KEYCTX_RXMK_SIZE_S 0
+#define TLS_KEYCTX_RXMK_SIZE_M 0x7
+#define TLS_KEYCTX_RXMK_SIZE_V(x) ((x) << TLS_KEYCTX_RXMK_SIZE_S)
+
 #define CHCR_HASH_MAX_DIGEST_SIZE 64
 #define CHCR_MAX_SHA_DIGEST_SIZE 64
 
@@ -176,6 +209,15 @@
  KEY_CONTEXT_SALT_PRESENT_V(1) | \
  KEY_CONTEXT_CTX_LEN_V((ctx_len)))
 
+#define  FILL_KEY_CRX_HDR(ck_size, mk_size, d_ck, opad, ctx_len) \
+   htonl(TLS_KEYCTX_RXMK_SIZE_V(mk_size) | \
+ TLS_KEYCTX_RXCK_SIZE_V(ck_size) | \
+ TLS_KEYCTX_RX_VALID_V(1) | \
+ TLS_KEYCTX_RX_SEQCTR_V(3) | \
+ TLS_KEYCTX_RXAUTH_MODE_V(4) | \
+ TLS_KEYCTX_RXCIPH_MODE_V(2) | \
+ TLS_KEYCTX_RXFLIT_CNT_V((ctx_len)))
+
 #define FILL_WR_OP_CCTX_SIZE \
htonl( \
FW_CRYPTO_LOOKASIDE_WR_OPCODE_V( \
diff --git a/drivers/crypto/chelsio/chcr_core.h 
b/drivers/crypto/chelsio/chcr_core.h
index 3c29ee0..77056a9 100644
--- a/drivers/crypto/chelsio/chcr_core.h
+++ b/drivers/crypto/chelsio/chcr_core.h
@@ -65,10 +65,58 @@
 struct _key_ctx {
__be32 ctx_hdr;
u8 salt[MAX_SALT];
-   __be64 reserverd;
+   __be64 iv_to_auth;
unsigned char key[0];
 };
 
+#define KEYCTX_TX_WR_IV_S  55
+#define KEYCTX_TX_WR_IV_M  0x1ffULL
+#define KEYCTX_TX_WR_IV_V(x) ((x) << KEYCTX_TX_WR_IV_S)
+#define KEYCTX_TX_WR_IV_G(x) \
+   (((x) >> KEYCTX_TX_WR_IV_S) & KEYCTX_TX_WR_IV_M)
+
+#define KEYCTX_TX_WR_AAD_S 47
+#define KEYCTX_TX_WR_AAD_M 0xffULL
+#define KEYCTX_TX_WR_AAD_V(x) ((x) << KEYCTX_TX_WR_AAD_S)
+#define KEYCTX_TX_WR_AAD_G(x) (((x) >> KEYCTX_TX_WR_AAD_S) & \
+   KEYCTX_TX_WR_AAD_M)
+
+#define KEYCTX_TX_WR_AADST_S 39
+#define KEYCTX_TX_WR_AADST_M 0xffULL
+#define KEYCTX_TX_WR_AADST_V(x) ((x) << KEYCTX_TX_WR_AADST_S)
+#define KEYCTX_TX_WR_AADST_G(x) \
+   (((x) >> KEYCTX_TX_WR_AADST_S) & KEYCTX_TX_WR_AADST_M)
+
+#define KEYCTX_TX_WR_CIPHER_S 30
+#define KEYCTX_TX_WR_CIPHER_M 0x1ffULL
+#define KEYCTX_TX_WR_CIPHER_V(x) ((x) << KEYCTX_TX_WR_CIPHER_S)
+#define KEYCTX_TX_WR_CIPHER_G(x) \
+   (((x) >> KEYCTX_TX_WR_CIPHER_S) & KEYCTX_TX_WR_CIPHER_M)
+
+#define KEYCTX_TX_WR_CIPHERST_S 23
+#define KEYCTX_TX_WR_CIPHERST_M 0x7f
+#define KEYCTX_TX_WR_CIPHERST_V(x) ((x) << KEYCTX_TX_WR_CIPHERST_S)
+#define KEYCTX_TX_WR_CIPHERST_G(x) \
+   (((x) >> KEYCTX_TX_WR_CIPHERST_S) & KEYCTX_TX_WR_CIPHERST_M)
+
+#define KEYCTX_TX_WR_AUTH_S 14
+#define KEYCTX_TX_WR_AUTH_M 0x1ff
+#define KEYCTX_TX_WR_AUTH_V(x) ((x) << KEYCTX_TX_WR_AUTH_S)
+#define KEYCTX_TX_WR_AUTH_G(x) \
+   (((x) >> KEYCTX_TX_WR_AUTH_S) & KEYCTX_TX_WR_AUTH_M)
+
+#define KEYCTX_TX_WR_AUTHST_S 7
+#define KEYCTX_TX_WR_AUTHST_M 0x7f
+#define KEYCTX_TX_WR_AUTHST_V(x) ((x) << KEYCTX_TX_WR_AUTHST_S)
+#define KEYCTX_TX_WR_AUTHST_G(x) \
+   (((x) >> KEYCTX_TX_WR_AUTHST_S) & KEYCTX_TX_WR_AUTHST_M)
+
+#define KEYCTX_TX_WR_AUTHIN_S 0
+#define KEYCTX_TX_WR_AUTHIN_M 0x7f
+#define KEYCTX_TX_WR_AUTHIN_V(x) ((x) << KEYCTX_TX_WR_AUTHIN_S)
+#define KEYCTX_TX_WR_AUTHIN_G(x) \
+   (((x) >> KEYCTX_TX_WR_AUTHIN_S) & KEYCTX_TX_WR_AUTHIN_M)
+
 struct chcr_wr {
struct fw_crypto_lookaside_wr wreq;
struct ulp_txpkt ulptx;
@@ -90,6 +138,11 @@ struct uld_ctx {
struct chcr_dev 

[Crypto v5 08/12] chtls: Key program

2018-02-14 Thread Atul Gupta
Program the tx and rx key on chip.

Signed-off-by: Atul Gupta 
---
 drivers/crypto/chelsio/chtls/chtls_hw.c | 394 
 1 file changed, 394 insertions(+)
 create mode 100644 drivers/crypto/chelsio/chtls/chtls_hw.c

diff --git a/drivers/crypto/chelsio/chtls/chtls_hw.c 
b/drivers/crypto/chelsio/chtls/chtls_hw.c
new file mode 100644
index 000..c3e17159
--- /dev/null
+++ b/drivers/crypto/chelsio/chtls/chtls_hw.c
@@ -0,0 +1,394 @@
+/*
+ * Copyright (c) 2017 Chelsio Communications, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Written by: Atul Gupta (atul.gu...@chelsio.com)
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "chtls.h"
+#include "chtls_cm.h"
+
+static void __set_tcb_field_direct(struct chtls_sock *csk,
+  struct cpl_set_tcb_field *req, u16 word,
+  u64 mask, u64 val, u8 cookie, int no_reply)
+{
+   struct ulptx_idata *sc;
+
+   INIT_TP_WR_CPL(req, CPL_SET_TCB_FIELD, csk->tid);
+   req->wr.wr_mid |= htonl(FW_WR_FLOWID_V(csk->tid));
+   req->reply_ctrl = htons(NO_REPLY_V(no_reply) |
+   QUEUENO_V(csk->rss_qid));
+   req->word_cookie = htons(TCB_WORD_V(word) | TCB_COOKIE_V(cookie));
+   req->mask = cpu_to_be64(mask);
+   req->val = cpu_to_be64(val);
+   sc = (struct ulptx_idata *)(req + 1);
+   sc->cmd_more = htonl(ULPTX_CMD_V(ULP_TX_SC_NOOP));
+   sc->len = htonl(0);
+}
+
+static void __set_tcb_field(struct sock *sk, struct sk_buff *skb, u16 word,
+   u64 mask, u64 val, u8 cookie, int no_reply)
+{
+   struct chtls_sock *csk = rcu_dereference_sk_user_data(sk);
+   struct cpl_set_tcb_field *req;
+   struct ulptx_idata *sc;
+   unsigned int wrlen = roundup(sizeof(*req) + sizeof(*sc), 16);
+
+   req = (struct cpl_set_tcb_field *)__skb_put(skb, wrlen);
+   __set_tcb_field_direct(csk, req, word, mask, val, cookie, no_reply);
+   set_wr_txq(skb, CPL_PRIORITY_CONTROL, csk->port_id);
+}
+
+static int chtls_set_tcb_field(struct sock *sk, u16 word, u64 mask, u64 val)
+{
+   struct chtls_sock *csk = rcu_dereference_sk_user_data(sk);
+   struct sk_buff *skb;
+   struct cpl_set_tcb_field *req;
+   struct ulptx_idata *sc;
+   unsigned int wrlen = roundup(sizeof(*req) + sizeof(*sc), 16);
+   unsigned int credits_needed = DIV_ROUND_UP(wrlen, 16);
+
+   skb = alloc_skb(wrlen, GFP_ATOMIC);
+   if (!skb)
+   return -ENOMEM;
+
+   __set_tcb_field(sk, skb, word, mask, val, 0, 1);
+   set_queue(skb, (csk->txq_idx << 1) | CPL_PRIORITY_DATA, sk);
+   csk->wr_credits -= credits_needed;
+   csk->wr_unacked += credits_needed;
+   enqueue_wr(csk, skb);
+   cxgb4_ofld_send(csk->egress_dev, skb);
+   return 0;
+}
+
+/*
+ * Set one of the t_flags bits in the TCB.
+ */
+int chtls_set_tcb_tflag(struct sock *sk, unsigned int bit_pos, int val)
+{
+   return chtls_set_tcb_field(sk, 1, 1ULL << bit_pos,
+   val << bit_pos);
+}
+
+static int chtls_set_tcb_keyid(struct sock *sk, int keyid)
+{
+   return chtls_set_tcb_field(sk, 31, 0xULL, keyid);
+}
+
+static int chtls_set_tcb_seqno(struct sock *sk)
+{
+   return chtls_set_tcb_field(sk, 28, ~0ULL, 0);
+}
+
+static int chtls_set_tcb_quiesce(struct sock *sk, int val)
+{
+   return chtls_set_tcb_field(sk, 1, (1ULL << TF_RX_QUIESCE_S),
+  TF_RX_QUIESCE_V(val));
+}
+
+static void *chtls_alloc_mem(unsigned long size)
+{
+   void *p = kmalloc(size, GFP_KERNEL);
+
+   if (!p)
+   p = vmalloc(size);
+   if (p)
+   memset(p, 0, size);
+   return p;
+}
+
+static void chtls_free_mem(void *addr)
+{
+   unsigned long p = (unsigned long)addr;
+
+   if (p >= VMALLOC_START && p < VMALLOC_END)
+   vfree(addr);
+   else
+   kfree(addr);
+}
+
+/* TLS Key bitmap processing */
+int chtls_init_kmap(struct chtls_dev *cdev, struct cxgb4_lld_info *lldi)
+{
+   unsigned int num_key_ctx, bsize;
+
+   num_key_ctx = (lldi->vr->key.size / TLS_KEY_CONTEXT_SZ);
+   bsize = BITS_TO_LONGS(num_key_ctx);
+
+   cdev->kmap.size = num_key_ctx;
+   cdev->kmap.available = bsize;
+   cdev->kmap.addr = chtls_alloc_mem(sizeof(*cdev->kmap.addr) *
+ bsize);
+   if (!cdev->kmap.addr)
+   return -1;
+
+   cdev->kmap.start = lldi->vr->key.start;
+   spin_lock_init(>kmap.lock);
+   return 0;
+}
+
+void chtls_free_kmap(struct chtls_dev *cdev)
+{
+   if (cdev->kmap.addr)
+   chtls_free_mem(cdev->kmap.addr);
+}
+
+static int 

[Crypto v5 05/12] cxgb4: Inline TLS FW Interface

2018-02-14 Thread Atul Gupta
Key area size in hw-config file. CPL struct for TLS request
and response. Work request for Inline TLS.

Signed-off-by: Atul Gupta 
---
 drivers/net/ethernet/chelsio/cxgb4/t4_msg.h   | 121 ++-
 drivers/net/ethernet/chelsio/cxgb4/t4_regs.h  |   2 +
 drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h | 165 +-
 3 files changed, 283 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h 
b/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h
index 7e12f24..9a56e0d 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h
@@ -81,6 +81,7 @@ enum {
CPL_RX_ISCSI_CMP  = 0x45,
CPL_TRACE_PKT_T5  = 0x48,
CPL_RX_ISCSI_DDP  = 0x49,
+   CPL_RX_TLS_CMP= 0x4E,
 
CPL_RDMA_READ_REQ = 0x60,
 
@@ -88,6 +89,7 @@ enum {
CPL_ACT_OPEN_REQ6 = 0x83,
 
CPL_TX_TLS_PDU =0x88,
+   CPL_TX_TLS_SFO= 0x89,
CPL_TX_SEC_PDU= 0x8A,
CPL_TX_TLS_ACK= 0x8B,
 
@@ -97,6 +99,7 @@ enum {
CPL_RX_MPS_PKT= 0xAF,
 
CPL_TRACE_PKT = 0xB0,
+   CPL_TLS_DATA  = 0xB1,
CPL_ISCSI_DATA= 0xB2,
 
CPL_FW4_MSG   = 0xC0,
@@ -150,6 +153,7 @@ enum {
ULP_MODE_RDMA  = 4,
ULP_MODE_TCPDDP= 5,
ULP_MODE_FCOE  = 6,
+   ULP_MODE_TLS   = 8,
 };
 
 enum {
@@ -1414,6 +1418,14 @@ struct cpl_tx_data {
 #define TX_FORCE_S 13
 #define TX_FORCE_V(x)  ((x) << TX_FORCE_S)
 
+#define TX_SHOVE_S14
+#define TX_SHOVE_V(x) ((x) << TX_SHOVE_S)
+
+#define TX_ULP_MODE_S10
+#define TX_ULP_MODE_M0x7
+#define TX_ULP_MODE_V(x) ((x) << TX_ULP_MODE_S)
+#define TX_ULP_MODE_G(x) (((x) >> TX_ULP_MODE_S) & TX_ULP_MODE_M)
+
 #define T6_TX_FORCE_S  20
 #define T6_TX_FORCE_V(x)   ((x) << T6_TX_FORCE_S)
 #define T6_TX_FORCE_F  T6_TX_FORCE_V(1U)
@@ -1428,12 +1440,21 @@ enum {
ULP_TX_SC_NOOP = 0x80,
ULP_TX_SC_IMM  = 0x81,
ULP_TX_SC_DSGL = 0x82,
-   ULP_TX_SC_ISGL = 0x83
+   ULP_TX_SC_ISGL = 0x83,
+   ULP_TX_SC_MEMRD = 0x86
 };
 
 #define ULPTX_CMD_S24
 #define ULPTX_CMD_V(x) ((x) << ULPTX_CMD_S)
 
+#define ULPTX_LEN16_S0
+#define ULPTX_LEN16_M0xFF
+#define ULPTX_LEN16_V(x) ((x) << ULPTX_LEN16_S)
+
+#define ULP_TX_SC_MORE_S 23
+#define ULP_TX_SC_MORE_V(x) ((x) << ULP_TX_SC_MORE_S)
+#define ULP_TX_SC_MORE_F  ULP_TX_SC_MORE_V(1U)
+
 struct ulptx_sge_pair {
__be32 len[2];
__be64 addr[2];
@@ -1948,4 +1969,102 @@ enum {
X_CPL_RX_MPS_PKT_TYPE_QFC   = 1 << 2,
X_CPL_RX_MPS_PKT_TYPE_PTP   = 1 << 3
 };
+
+struct cpl_tx_tls_sfo {
+   __be32 op_to_seg_len;
+   __be32 pld_len;
+   __be32 type_protover;
+   __be32 r1_lo;
+   __be32 seqno_numivs;
+   __be32 ivgen_hdrlen;
+   __be64 scmd1;
+};
+
+/* cpl_tx_tls_sfo macros */
+#define CPL_TX_TLS_SFO_OPCODE_S 24
+#define CPL_TX_TLS_SFO_OPCODE_V(x)  ((x) << CPL_TX_TLS_SFO_OPCODE_S)
+
+#define CPL_TX_TLS_SFO_DATA_TYPE_S  20
+#define CPL_TX_TLS_SFO_DATA_TYPE_V(x)   ((x) << CPL_TX_TLS_SFO_DATA_TYPE_S)
+
+#define CPL_TX_TLS_SFO_CPL_LEN_S16
+#define CPL_TX_TLS_SFO_CPL_LEN_V(x) ((x) << CPL_TX_TLS_SFO_CPL_LEN_S)
+
+#define CPL_TX_TLS_SFO_SEG_LEN_S0
+#define CPL_TX_TLS_SFO_SEG_LEN_M0x
+#define CPL_TX_TLS_SFO_SEG_LEN_V(x) ((x) << CPL_TX_TLS_SFO_SEG_LEN_S)
+#define CPL_TX_TLS_SFO_SEG_LEN_G(x) \
+   (((x) >> CPL_TX_TLS_SFO_SEG_LEN_S) & CPL_TX_TLS_SFO_SEG_LEN_M)
+
+#define CPL_TX_TLS_SFO_TYPE_S   24
+#define CPL_TX_TLS_SFO_TYPE_M   0xff
+#define CPL_TX_TLS_SFO_TYPE_V(x)((x) << CPL_TX_TLS_SFO_TYPE_S)
+#define CPL_TX_TLS_SFO_TYPE_G(x)\
+   (((x) >> CPL_TX_TLS_SFO_TYPE_S) & CPL_TX_TLS_SFO_TYPE_M)
+
+#define CPL_TX_TLS_SFO_PROTOVER_S   8
+#define CPL_TX_TLS_SFO_PROTOVER_M   0x
+#define CPL_TX_TLS_SFO_PROTOVER_V(x)((x) << CPL_TX_TLS_SFO_PROTOVER_S)
+#define CPL_TX_TLS_SFO_PROTOVER_G(x)\
+   (((x) >> CPL_TX_TLS_SFO_PROTOVER_S) & CPL_TX_TLS_SFO_PROTOVER_M)
+
+struct cpl_tls_data {
+   struct rss_header rsshdr;
+   union opcode_tid ot;
+   __be32 length_pkd;
+   __be32 seq;
+   __be32 r1;
+};
+
+#define CPL_TLS_DATA_OPCODE_S   24
+#define CPL_TLS_DATA_OPCODE_M   0xff
+#define CPL_TLS_DATA_OPCODE_V(x)((x) << CPL_TLS_DATA_OPCODE_S)
+#define CPL_TLS_DATA_OPCODE_G(x)\
+   (((x) >> CPL_TLS_DATA_OPCODE_S) & CPL_TLS_DATA_OPCODE_M)
+
+#define CPL_TLS_DATA_TID_S  0
+#define CPL_TLS_DATA_TID_M  0xff
+#define CPL_TLS_DATA_TID_V(x)   ((x) << CPL_TLS_DATA_TID_S)
+#define CPL_TLS_DATA_TID_G(x)   \
+   (((x) >> CPL_TLS_DATA_TID_S) & CPL_TLS_DATA_TID_M)
+
+#define CPL_TLS_DATA_LENGTH_S   0
+#define CPL_TLS_DATA_LENGTH_M   0x
+#define 

[Crypto v5 12/12] Makefile Kconfig

2018-02-14 Thread Atul Gupta
Entry for Inline TLS as another driver dependent on cxgb4 and chcr

Signed-off-by: Atul Gupta 
---
 drivers/crypto/chelsio/Kconfig| 11 +++
 drivers/crypto/chelsio/Makefile   |  1 +
 drivers/crypto/chelsio/chtls/Makefile |  4 
 3 files changed, 16 insertions(+)
 create mode 100644 drivers/crypto/chelsio/chtls/Makefile

diff --git a/drivers/crypto/chelsio/Kconfig b/drivers/crypto/chelsio/Kconfig
index 5ae9f87..930d82d 100644
--- a/drivers/crypto/chelsio/Kconfig
+++ b/drivers/crypto/chelsio/Kconfig
@@ -29,3 +29,14 @@ config CHELSIO_IPSEC_INLINE
 default n
 ---help---
   Enable support for IPSec Tx Inline.
+
+config CRYPTO_DEV_CHELSIO_TLS
+tristate "Chelsio Crypto Inline TLS Driver"
+depends on CHELSIO_T4
+depends on TLS
+select CRYPTO_DEV_CHELSIO
+---help---
+  Support Chelsio Inline TLS with Chelsio crypto accelerator.
+
+  To compile this driver as a module, choose M here: the module
+  will be called chtls.
diff --git a/drivers/crypto/chelsio/Makefile b/drivers/crypto/chelsio/Makefile
index eaecaf1..639e571 100644
--- a/drivers/crypto/chelsio/Makefile
+++ b/drivers/crypto/chelsio/Makefile
@@ -3,3 +3,4 @@ ccflags-y := -Idrivers/net/ethernet/chelsio/cxgb4
 obj-$(CONFIG_CRYPTO_DEV_CHELSIO) += chcr.o
 chcr-objs :=  chcr_core.o chcr_algo.o
 chcr-$(CONFIG_CHELSIO_IPSEC_INLINE) += chcr_ipsec.o
+obj-$(CONFIG_CRYPTO_DEV_CHELSIO_TLS) += chtls/
diff --git a/drivers/crypto/chelsio/chtls/Makefile 
b/drivers/crypto/chelsio/chtls/Makefile
new file mode 100644
index 000..df13795
--- /dev/null
+++ b/drivers/crypto/chelsio/chtls/Makefile
@@ -0,0 +1,4 @@
+ccflags-y := -Idrivers/net/ethernet/chelsio/cxgb4 -Idrivers/crypto/chelsio/
+
+obj-$(CONFIG_CRYPTO_DEV_CHELSIO_TLS) += chtls.o
+chtls-objs := chtls_main.o chtls_cm.o chtls_io.o chtls_hw.o
-- 
1.8.3.1



[Crypto v5 06/12] cxgb4: LLD driver changes to enable TLS

2018-02-14 Thread Atul Gupta
Read FW capability. Read key area size. Dump the TLS record count.

Signed-off-by: Atul Gupta 
---
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c | 18 +++-
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c| 32 +--
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h |  7 ++
 drivers/net/ethernet/chelsio/cxgb4/sge.c   | 98 +-
 4 files changed, 142 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c 
b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
index cf47183..cfc9210 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
@@ -2826,8 +2826,8 @@ static int meminfo_show(struct seq_file *seq, void *v)
"Tx payload:", "Rx payload:", "LE hash:", "iSCSI region:",
"TDDP region:", "TPT region:", "STAG region:", "RQ region:",
"RQUDP region:", "PBL region:", "TXPBL region:",
-   "DBVFIFO region:", "ULPRX state:", "ULPTX state:",
-   "On-chip queues:"
+   "TLSKey region:", "DBVFIFO region:", "ULPRX state:",
+   "ULPTX state:", "On-chip queues:"
};
 
int i, n;
@@ -2943,6 +2943,12 @@ static int meminfo_show(struct seq_file *seq, void *v)
ulp_region(RX_RQUDP);
ulp_region(RX_PBL);
ulp_region(TX_PBL);
+   if (adap->params.crypto & FW_CAPS_CONFIG_TLS_INLINE) {
+   ulp_region(RX_TLS_KEY);
+   } else {
+   md->base = 0;
+   md->idx = ARRAY_SIZE(region);
+   }
 #undef ulp_region
md->base = 0;
md->idx = ARRAY_SIZE(region);
@@ -3098,6 +3104,14 @@ static int chcr_show(struct seq_file *seq, void *v)
   atomic_read(>chcr_stats.fallback));
seq_printf(seq, "IPSec PDU: %10u\n",
   atomic_read(>chcr_stats.ipsec_cnt));
+
+   seq_puts(seq, "\nChelsio Inline TLS Stats\n");
+   seq_printf(seq, "TLS PDU Tx: %u\n",
+  atomic_read(>chcr_stats.tls_pdu_tx));
+   seq_printf(seq, "TLS PDU Rx: %u\n",
+  atomic_read(>chcr_stats.tls_pdu_rx));
+   seq_printf(seq, "TLS Keys (DDR) Count: %u\n",
+  atomic_read(>chcr_stats.tls_key));
return 0;
 }
 
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c 
b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index 05a4abf..60eb18b 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -4086,18 +4086,32 @@ static int adap_init0(struct adapter *adap)
adap->num_ofld_uld += 2;
}
if (caps_cmd.cryptocaps) {
-   /* Should query params here...TODO */
-   params[0] = FW_PARAM_PFVF(NCRYPTO_LOOKASIDE);
-   ret = t4_query_params(adap, adap->mbox, adap->pf, 0, 2,
- params, val);
-   if (ret < 0) {
-   if (ret != -EINVAL)
+   if (ntohs(caps_cmd.cryptocaps) &
+   FW_CAPS_CONFIG_CRYPTO_LOOKASIDE) {
+   params[0] = FW_PARAM_PFVF(NCRYPTO_LOOKASIDE);
+   ret = t4_query_params(adap, adap->mbox, adap->pf, 0,
+ 2, params, val);
+   if (ret < 0) {
+   if (ret != -EINVAL)
+   goto bye;
+   } else {
+   adap->vres.ncrypto_fc = val[0];
+   }
+   adap->num_ofld_uld += 1;
+   }
+   if (ntohs(caps_cmd.cryptocaps) &
+   FW_CAPS_CONFIG_TLS_INLINE) {
+   params[0] = FW_PARAM_PFVF(TLS_START);
+   params[1] = FW_PARAM_PFVF(TLS_END);
+   ret = t4_query_params(adap, adap->mbox, adap->pf, 0,
+ 2, params, val);
+   if (ret < 0)
goto bye;
-   } else {
-   adap->vres.ncrypto_fc = val[0];
+   adap->vres.key.start = val[0];
+   adap->vres.key.size = val[1] - val[0] + 1;
+   adap->num_uld += 1;
}
adap->params.crypto = ntohs(caps_cmd.cryptocaps);
-   adap->num_uld += 1;
}
 #undef FW_PARAM_PFVF
 #undef FW_PARAM_DEV
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h 
b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
index 1d37672..55863f6 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
@@ -237,6 +237,7 @@ enum cxgb4_uld {
CXGB4_ULD_ISCSI,
CXGB4_ULD_ISCSIT,
CXGB4_ULD_CRYPTO,
+   CXGB4_ULD_TLS,
CXGB4_ULD_MAX
 };
 
@@ -287,6 +288,7 @@ struct cxgb4_virt_res { 

[Crypto v5 11/12] chtls: Register the chtls Inline TLS with net tls

2018-02-14 Thread Atul Gupta
Add new uld driver for Inline TLS support. Register ULP for chtls.
Setsockopt to program key on chip. support AES GCM key size 128.

Signed-off-by: Atul Gupta 
---
 drivers/crypto/chelsio/chtls/chtls_main.c | 574 ++
 include/uapi/linux/tls.h  |   1 +
 2 files changed, 575 insertions(+)
 create mode 100644 drivers/crypto/chelsio/chtls/chtls_main.c

diff --git a/drivers/crypto/chelsio/chtls/chtls_main.c 
b/drivers/crypto/chelsio/chtls/chtls_main.c
new file mode 100644
index 000..66d4ce9
--- /dev/null
+++ b/drivers/crypto/chelsio/chtls/chtls_main.c
@@ -0,0 +1,574 @@
+/*
+ * Copyright (c) 2017 Chelsio Communications, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Written by: Atul Gupta (atul.gu...@chelsio.com)
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "chtls.h"
+#include "chtls_cm.h"
+
+#define DRV_NAME "chtls"
+
+/*
+ * chtls device management
+ * maintains a list of the chtls devices
+ */
+static LIST_HEAD(cdev_list);
+static DEFINE_MUTEX(cdev_mutex);
+static DEFINE_MUTEX(cdev_list_lock);
+
+static struct proto chtls_cpl_prot;
+static DEFINE_MUTEX(notify_mutex);
+static RAW_NOTIFIER_HEAD(listen_notify_list);
+struct request_sock_ops chtls_rsk_ops;
+static uint send_page_order = (14 - PAGE_SHIFT < 0) ? 0 : 14 - PAGE_SHIFT;
+
+static int register_listen_notifier(struct notifier_block *nb)
+{
+   int err;
+
+   mutex_lock(_mutex);
+   err = raw_notifier_chain_register(_notify_list, nb);
+   mutex_unlock(_mutex);
+   return err;
+}
+
+static int unregister_listen_notifier(struct notifier_block *nb)
+{
+   int err;
+
+   mutex_lock(_mutex);
+   err = raw_notifier_chain_unregister(_notify_list, nb);
+   mutex_unlock(_mutex);
+   return err;
+}
+
+static int listen_notify_handler(struct notifier_block *this,
+unsigned long event, void *data)
+{
+   struct sock *sk = data;
+   struct chtls_dev *cdev;
+   int ret =  NOTIFY_DONE;
+
+   switch (event) {
+   case CHTLS_LISTEN_START:
+   case CHTLS_LISTEN_STOP:
+   mutex_lock(_list_lock);
+   list_for_each_entry(cdev, _list, list) {
+   if (event == CHTLS_LISTEN_START)
+   ret = chtls_listen_start(cdev, sk);
+   else
+   chtls_listen_stop(cdev, sk);
+   }
+   mutex_unlock(_list_lock);
+   break;
+   }
+   return ret;
+}
+
+static struct notifier_block listen_notifier = {
+   .notifier_call = listen_notify_handler
+};
+
+static int listen_backlog_rcv(struct sock *sk, struct sk_buff *skb)
+{
+   if (likely(skb_transport_header(skb) != skb_network_header(skb)))
+   return tcp_v4_do_rcv(sk, skb);
+   BLOG_SKB_CB(skb)->backlog_rcv(sk, skb);
+   return 0;
+}
+
+static int chtls_start_listen(struct sock *sk)
+{
+   int err;
+
+   if (sk->sk_protocol != IPPROTO_TCP)
+   return -EPROTONOSUPPORT;
+
+   if (sk->sk_family == PF_INET &&
+   LOOPBACK(inet_sk(sk)->inet_rcv_saddr))
+   return -EADDRNOTAVAIL;
+
+   sk->sk_backlog_rcv = listen_backlog_rcv;
+   mutex_lock(_mutex);
+   err = raw_notifier_call_chain(_notify_list, 0, sk);
+   mutex_unlock(_mutex);
+   return err;
+}
+
+static int chtls_stop_listen(struct sock *sk)
+{
+   if (sk->sk_protocol != IPPROTO_TCP)
+   return -EPROTONOSUPPORT;
+
+   mutex_lock(_mutex);
+   raw_notifier_call_chain(_notify_list, 1, sk);
+   mutex_unlock(_mutex);
+   return 0;
+}
+
+int chtls_netdev(struct tls_device *dev,
+struct net_device *netdev)
+{
+   struct chtls_dev *cdev = to_chtls_dev(dev);
+   int i;
+
+   for (i = 0; i < cdev->lldi->nports; i++)
+   if (cdev->ports[i] == netdev)
+   return 1;
+
+   return 0;
+}
+
+int chtls_inline_feature(struct tls_device *dev)
+{
+   struct chtls_dev *cdev = to_chtls_dev(dev);
+   struct net_device *netdev;
+   int i;
+
+   for (i = 0; i < cdev->lldi->nports; i++) {
+   netdev = cdev->ports[i];
+   if (netdev->features & NETIF_F_HW_TLS_INLINE)
+   return 1;
+   }
+   return 1;
+}
+
+int chtls_create_hash(struct tls_device *dev, struct sock *sk)
+{
+   if (sk->sk_state == TCP_LISTEN)
+   return chtls_start_listen(sk);
+   return 0;
+}
+
+void chtls_destroy_hash(struct tls_device *dev, struct sock *sk)
+{
+   if (sk->sk_state == TCP_LISTEN)
+   chtls_stop_listen(sk);
+}
+
+static void chtls_register_dev(struct chtls_dev *cdev)
+{
+   

[Crypto v5 10/12] chtls: Inline crypto request Tx/Rx

2018-02-14 Thread Atul Gupta
TLS handler for record transmit and receive.
Create Inline TLS work request and post to FW.

Signed-off-by: Atul Gupta 
---
 drivers/crypto/chelsio/chtls/chtls_io.c | 1867 +++
 1 file changed, 1867 insertions(+)
 create mode 100644 drivers/crypto/chelsio/chtls/chtls_io.c

diff --git a/drivers/crypto/chelsio/chtls/chtls_io.c 
b/drivers/crypto/chelsio/chtls/chtls_io.c
new file mode 100644
index 000..a0f03fb
--- /dev/null
+++ b/drivers/crypto/chelsio/chtls/chtls_io.c
@@ -0,0 +1,1867 @@
+/*
+ * Copyright (c) 2017 Chelsio Communications, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Written by: Atul Gupta (atul.gu...@chelsio.com)
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "chtls.h"
+#include "chtls_cm.h"
+
+static bool is_tls_hw(struct chtls_sock *csk)
+{
+   return csk->tlshws.ofld;
+}
+
+static bool is_tls_rx(struct chtls_sock *csk)
+{
+   return (csk->tlshws.rxkey >= 0);
+}
+
+static bool is_tls_tx(struct chtls_sock *csk)
+{
+   return (csk->tlshws.txkey >= 0);
+}
+
+static bool is_tls_skb(struct chtls_sock *csk, const struct sk_buff *skb)
+{
+   return (is_tls_hw(csk) && skb_ulp_tls_skb_flags(skb));
+}
+
+static int key_size(void *sk)
+{
+   return 16; /* Key on DDR */
+}
+
+#define ceil(x, y) \
+   ({ unsigned long __x = (x), __y = (y); (__x + __y - 1) / __y; })
+
+static int data_sgl_len(const struct sk_buff *skb)
+{
+   unsigned int cnt;
+
+   cnt = skb_shinfo(skb)->nr_frags;
+   return (sgl_len(cnt) * 8);
+}
+
+static int nos_ivs(struct sock *sk, unsigned int size)
+{
+   struct chtls_sock *csk = rcu_dereference_sk_user_data(sk);
+
+   return ceil(size, csk->tlshws.mfs);
+}
+
+#define TLS_WR_CPL_LEN \
+   (sizeof(struct fw_tlstx_data_wr) + \
+   sizeof(struct cpl_tx_tls_sfo))
+
+static int is_ivs_imm(struct sock *sk, const struct sk_buff *skb)
+{
+   int ivs_size = nos_ivs(sk, skb->len) * CIPHER_BLOCK_SIZE;
+   int hlen = TLS_WR_CPL_LEN + data_sgl_len(skb);
+
+   if ((hlen + key_size(sk) + ivs_size) <
+   MAX_IMM_OFLD_TX_DATA_WR_LEN) {
+   ULP_SKB_CB(skb)->ulp.tls.iv = 1;
+   return 1;
+   }
+   ULP_SKB_CB(skb)->ulp.tls.iv = 0;
+   return 0;
+}
+
+static int max_ivs_size(struct sock *sk, int size)
+{
+   return (nos_ivs(sk, size) * CIPHER_BLOCK_SIZE);
+}
+
+static int ivs_size(struct sock *sk, const struct sk_buff *skb)
+{
+   return (is_ivs_imm(sk, skb) ? (nos_ivs(sk, skb->len) *
+CIPHER_BLOCK_SIZE) : 0);
+}
+
+static int flowc_wr_credits(int nparams, int *flowclenp)
+{
+   int flowclen16, flowclen;
+
+   flowclen = offsetof(struct fw_flowc_wr, mnemval[nparams]);
+   flowclen16 = DIV_ROUND_UP(flowclen, 16);
+   flowclen = flowclen16 * 16;
+
+   if (flowclenp)
+   *flowclenp = flowclen;
+
+   return flowclen16;
+}
+
+static struct sk_buff *create_flowc_wr_skb(struct sock *sk,
+  struct fw_flowc_wr *flowc,
+  int flowclen)
+{
+   struct chtls_sock *csk = rcu_dereference_sk_user_data(sk);
+   struct sk_buff *skb;
+
+   skb = alloc_skb(flowclen, GFP_ATOMIC);
+   if (!skb)
+   return NULL;
+
+   memcpy(__skb_put(skb, flowclen), flowc, flowclen);
+   set_queue(skb, (csk->txq_idx << 1) | CPL_PRIORITY_DATA, sk);
+
+   return skb;
+}
+
+static int send_flowc_wr(struct sock *sk, struct fw_flowc_wr *flowc,
+int flowclen)
+{
+   struct chtls_sock *csk = rcu_dereference_sk_user_data(sk);
+   bool syn_sent = (sk->sk_state == TCP_SYN_SENT);
+   struct tcp_sock *tp = tcp_sk(sk);
+   int flowclen16 = flowclen / 16;
+   struct sk_buff *skb;
+
+   if (csk_flag(sk, CSK_TX_DATA_SENT)) {
+   skb = create_flowc_wr_skb(sk, flowc, flowclen);
+   if (!skb)
+   return -ENOMEM;
+
+   if (syn_sent)
+   __skb_queue_tail(>ooo_queue, skb);
+   else
+   skb_entail(sk, skb,
+  ULPCB_FLAG_NO_HDR | ULPCB_FLAG_NO_APPEND);
+   return 0;
+   }
+
+   if (!syn_sent) {
+   int ret;
+
+   ret = cxgb4_immdata_send(csk->egress_dev,
+csk->txq_idx,
+flowc, flowclen);
+   if (!ret)
+   return flowclen16;
+   }
+   skb = create_flowc_wr_skb(sk, flowc, flowclen);
+   if (!skb)
+   return -ENOMEM;
+   send_or_defer(sk, tp, skb, 0);
+   return flowclen16;
+}
+
+static u8 

[Crypto v5 01/12] tls: tls_device struct to register TLS drivers

2018-02-14 Thread Atul Gupta
tls_device structure to register Inline TLS drivers
with net/tls

Signed-off-by: Atul Gupta 
---
 include/net/tls.h | 24 
 1 file changed, 24 insertions(+)

diff --git a/include/net/tls.h b/include/net/tls.h
index 936cfc5..6b64510 100644
--- a/include/net/tls.h
+++ b/include/net/tls.h
@@ -55,6 +55,28 @@
 
 #define TLS_AAD_SPACE_SIZE 13
 
+#define TLS_DEVICE_NAME_MAX 32
+
+enum {
+   TLS_BASE_TX,
+   TLS_SW_TX,
+   TLS_FULL_HW, /* TLS record processed Inline */
+   TLS_NUM_CONFIG,
+};
+extern struct proto tls_prots[TLS_NUM_CONFIG];
+
+struct tls_device {
+   char name[TLS_DEVICE_NAME_MAX];
+   struct list_head dev_list;
+
+   /* netdev present in registered inline tls driver */
+   int (*netdev)(struct tls_device *device,
+ struct net_device *netdev);
+   int (*feature)(struct tls_device *device);
+   int (*hash)(struct tls_device *device, struct sock *sk);
+   void (*unhash)(struct tls_device *device, struct sock *sk);
+};
+
 struct tls_sw_context {
struct crypto_aead *aead_send;
 
@@ -254,5 +276,7 @@ static inline struct tls_offload_context *tls_offload_ctx(
 
 int tls_proccess_cmsg(struct sock *sk, struct msghdr *msg,
  unsigned char *record_type);
+void tls_register_device(struct tls_device *device);
+void tls_unregister_device(struct tls_device *device);
 
 #endif /* _TLS_OFFLOAD_H */
-- 
1.8.3.1



[Crypto v5 09/12] chtls: CPL handler definition

2018-02-14 Thread Atul Gupta
CPL handlers for TLS session, record transmit and receive.

Signed-off-by: Atul Gupta 
---
 drivers/crypto/chelsio/chtls/chtls_cm.c | 2046 +++
 net/ipv4/tcp_minisocks.c|1 +
 2 files changed, 2047 insertions(+)
 create mode 100644 drivers/crypto/chelsio/chtls/chtls_cm.c

diff --git a/drivers/crypto/chelsio/chtls/chtls_cm.c 
b/drivers/crypto/chelsio/chtls/chtls_cm.c
new file mode 100644
index 000..670bac6
--- /dev/null
+++ b/drivers/crypto/chelsio/chtls/chtls_cm.c
@@ -0,0 +1,2046 @@
+/*
+ * Copyright (c) 2017 Chelsio Communications, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Written by: Atul Gupta (atul.gu...@chelsio.com)
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "chtls.h"
+#include "chtls_cm.h"
+
+extern struct request_sock_ops chtls_rsk_ops;
+
+/*
+ * State transitions and actions for close.  Note that if we are in SYN_SENT
+ * we remain in that state as we cannot control a connection while it's in
+ * SYN_SENT; such connections are allowed to establish and are then aborted.
+ */
+static unsigned char new_state[16] = {
+   /* current state: new state:  action: */
+   /* (Invalid)   */ TCP_CLOSE,
+   /* TCP_ESTABLISHED */ TCP_FIN_WAIT1 | TCP_ACTION_FIN,
+   /* TCP_SYN_SENT*/ TCP_SYN_SENT,
+   /* TCP_SYN_RECV*/ TCP_FIN_WAIT1 | TCP_ACTION_FIN,
+   /* TCP_FIN_WAIT1   */ TCP_FIN_WAIT1,
+   /* TCP_FIN_WAIT2   */ TCP_FIN_WAIT2,
+   /* TCP_TIME_WAIT   */ TCP_CLOSE,
+   /* TCP_CLOSE   */ TCP_CLOSE,
+   /* TCP_CLOSE_WAIT  */ TCP_LAST_ACK | TCP_ACTION_FIN,
+   /* TCP_LAST_ACK*/ TCP_LAST_ACK,
+   /* TCP_LISTEN  */ TCP_CLOSE,
+   /* TCP_CLOSING */ TCP_CLOSING,
+};
+
+static struct chtls_sock *chtls_sock_create(struct chtls_dev *cdev)
+{
+   struct chtls_sock *csk = kzalloc(sizeof(*csk), GFP_ATOMIC);
+
+   if (!csk)
+   return NULL;
+
+   csk->txdata_skb_cache = alloc_skb(TXDATA_SKB_LEN, GFP_ATOMIC);
+   if (!csk->txdata_skb_cache) {
+   kfree(csk);
+   return NULL;
+   }
+
+   kref_init(>kref);
+   csk->cdev = cdev;
+   skb_queue_head_init(>txq);
+   csk->wr_skb_head = NULL;
+   csk->wr_skb_tail = NULL;
+   csk->mss = MAX_MSS;
+   csk->tlshws.ofld = 1;
+   csk->tlshws.txkey = -1;
+   csk->tlshws.rxkey = -1;
+   csk->tlshws.mfs = TLS_MFS;
+   skb_queue_head_init(>tlshws.sk_recv_queue);
+   return csk;
+}
+
+static void chtls_sock_release(struct kref *ref)
+{
+   struct chtls_sock *csk =
+   container_of(ref, struct chtls_sock, kref);
+
+   kfree(csk);
+}
+
+static struct net_device *chtls_ipv4_netdev(struct chtls_dev *cdev,
+   struct sock *sk)
+{
+   struct net_device *ndev = cdev->ports[0];
+
+   if (likely(!inet_sk(sk)->inet_rcv_saddr))
+   return ndev;
+
+   ndev = ip_dev_find(_net, inet_sk(sk)->inet_rcv_saddr);
+   if (!ndev)
+   return NULL;
+
+   if (is_vlan_dev(ndev))
+   return vlan_dev_real_dev(ndev);
+   return ndev;
+}
+
+static void assign_rxopt(struct sock *sk, unsigned int opt)
+{
+   struct chtls_sock *csk = rcu_dereference_sk_user_data(sk);
+   struct tcp_sock *tp = tcp_sk(sk);
+   const struct chtls_dev *cdev;
+
+   cdev = csk->cdev;
+   tp->tcp_header_len   = sizeof(struct tcphdr);
+   tp->rx_opt.mss_clamp = cdev->mtus[TCPOPT_MSS_G(opt)] - 40;
+   tp->mss_cache= tp->rx_opt.mss_clamp;
+   tp->rx_opt.tstamp_ok = TCPOPT_TSTAMP_G(opt);
+   tp->rx_opt.snd_wscale= TCPOPT_SACK_G(opt);
+   tp->rx_opt.wscale_ok = TCPOPT_WSCALE_OK_G(opt);
+   SND_WSCALE(tp)   = TCPOPT_SND_WSCALE_G(opt);
+   if (!tp->rx_opt.wscale_ok)
+   tp->rx_opt.rcv_wscale = 0;
+   if (tp->rx_opt.tstamp_ok) {
+   tp->tcp_header_len += TCPOLEN_TSTAMP_ALIGNED;
+   tp->rx_opt.mss_clamp -= TCPOLEN_TSTAMP_ALIGNED;
+   } else if (csk->opt2 & TSTAMPS_EN_F) {
+   csk->opt2 &= ~TSTAMPS_EN_F;
+   csk->mtu_idx = TCPOPT_MSS_G(opt);
+   }
+}
+
+static void chtls_purge_rcv_queue(struct sock *sk)
+{
+   struct sk_buff *skb;
+
+   while ((skb = __skb_dequeue(>sk_receive_queue)) != NULL) {
+   skb_dst_set(skb, (void *)NULL);
+   kfree_skb(skb);
+   }
+}
+
+static void chtls_purge_write_queue(struct sock *sk)
+{
+   struct chtls_sock *csk = rcu_dereference_sk_user_data(sk);
+   struct sk_buff *skb;
+
+   while ((skb = __skb_dequeue(>txq))) {
+

[Crypto v5 02/12] ethtool: feature for Inline TLS in HW

2018-02-14 Thread Atul Gupta
Signed-off-by: Atul Gupta 
---
 include/linux/netdev_features.h | 2 ++
 net/core/ethtool.c  | 1 +
 2 files changed, 3 insertions(+)

diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h
index b1b0ca7..e1a33b7 100644
--- a/include/linux/netdev_features.h
+++ b/include/linux/netdev_features.h
@@ -77,6 +77,7 @@ enum {
NETIF_F_HW_ESP_BIT, /* Hardware ESP transformation offload 
*/
NETIF_F_HW_ESP_TX_CSUM_BIT, /* ESP with TX checksum offload */
NETIF_F_RX_UDP_TUNNEL_PORT_BIT, /* Offload of RX port for UDP tunnels */
+   NETIF_F_HW_TLS_INLINE_BIT,  /* Offload TLS record */
 
/*
 * Add your fresh new feature above and remember to update
@@ -142,6 +143,7 @@ enum {
 #define NETIF_F_HW_ESP __NETIF_F(HW_ESP)
 #define NETIF_F_HW_ESP_TX_CSUM __NETIF_F(HW_ESP_TX_CSUM)
 #defineNETIF_F_RX_UDP_TUNNEL_PORT  __NETIF_F(RX_UDP_TUNNEL_PORT)
+#define NETIF_F_HW_TLS_INLINE   __NETIF_F(HW_TLS_INLINE)
 
 #define for_each_netdev_feature(mask_addr, bit)\
for_each_set_bit(bit, (unsigned long *)mask_addr, NETDEV_FEATURE_COUNT)
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index f8fcf45..cac1c77 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -106,6 +106,7 @@ int ethtool_op_get_ts_info(struct net_device *dev, struct 
ethtool_ts_info *info)
[NETIF_F_HW_ESP_BIT] =   "esp-hw-offload",
[NETIF_F_HW_ESP_TX_CSUM_BIT] =   "esp-tx-csum-hw-offload",
[NETIF_F_RX_UDP_TUNNEL_PORT_BIT] =   "rx-udp_tunnel-port-offload",
+   [NETIF_F_HW_TLS_INLINE_BIT] ="tls-inline",
 };
 
 static const char
-- 
1.8.3.1



[Crypto v5 04/12] chtls: structure and macro definiton

2018-02-14 Thread Atul Gupta
Inline TLS state, connection management. Supporting macros definition.

Signed-off-by: Atul Gupta 
---
 drivers/crypto/chelsio/chtls/chtls.h| 487 
 drivers/crypto/chelsio/chtls/chtls_cm.h | 203 +
 2 files changed, 690 insertions(+)
 create mode 100644 drivers/crypto/chelsio/chtls/chtls.h
 create mode 100644 drivers/crypto/chelsio/chtls/chtls_cm.h

diff --git a/drivers/crypto/chelsio/chtls/chtls.h 
b/drivers/crypto/chelsio/chtls/chtls.h
new file mode 100644
index 000..c7b8d59
--- /dev/null
+++ b/drivers/crypto/chelsio/chtls/chtls.h
@@ -0,0 +1,487 @@
+/*
+ * Copyright (c) 2016 Chelsio Communications, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __CHTLS_H__
+#define __CHTLS_H__
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "t4fw_api.h"
+#include "t4_msg.h"
+#include "cxgb4.h"
+#include "cxgb4_uld.h"
+#include "l2t.h"
+#include "chcr_algo.h"
+#include "chcr_core.h"
+#include "chcr_crypto.h"
+
+#define CIPHER_BLOCK_SIZE   16
+#define MAX_IVS_PAGE256
+#define TLS_KEY_CONTEXT_SZ 64
+#define TLS_HEADER_LENGTH  5
+#define SCMD_CIPH_MODE_AES_GCM  2
+#define GCM_TAG_SIZE16
+#define AEAD_EXPLICIT_DATA_SIZE 8
+/* Any MFS size should work and come from openssl */
+#define TLS_MFS16384
+
+#define SOCK_INLINE (31)
+#define RSS_HDR sizeof(struct rss_header)
+
+enum {
+   CHTLS_KEY_CONTEXT_DSGL,
+   CHTLS_KEY_CONTEXT_IMM,
+   CHTLS_KEY_CONTEXT_DDR,
+};
+
+enum {
+   CHTLS_LISTEN_START,
+   CHTLS_LISTEN_STOP,
+};
+
+/* Flags for return value of CPL message handlers */
+enum {
+   CPL_RET_BUF_DONE = 1,   /* buffer processing done */
+   CPL_RET_BAD_MSG = 2,/* bad CPL message */
+   CPL_RET_UNKNOWN_TID = 4 /* unexpected unknown TID */
+};
+
+#define TLS_RCV_ST_READ_HEADER  0xF0
+#define TLS_RCV_ST_READ_BODY0xF1
+#define TLS_RCV_ST_READ_DONE0xF2
+#define TLS_RCV_ST_READ_NB  0xF3
+
+#define RSPQ_HASH_BITS 5
+#define LISTEN_INFO_HASH_SIZE 32
+struct listen_info {
+   struct listen_info *next;  /* Link to next entry */
+   struct sock *sk;   /* The listening socket */
+   unsigned int stid; /* The server TID */
+};
+
+enum {
+   T4_LISTEN_START_PENDING,
+   T4_LISTEN_STARTED
+};
+
+enum csk_flags {
+   CSK_CALLBACKS_CHKD, /* socket callbacks have been sanitized */
+   CSK_ABORT_REQ_RCVD, /* received one ABORT_REQ_RSS message */
+   CSK_TX_MORE_DATA,   /* sending ULP data; don't set SHOVE bit */
+   CSK_TX_WAIT_IDLE,   /* suspend Tx until in-flight data is ACKed */
+   CSK_ABORT_SHUTDOWN, /* shouldn't send more abort requests */
+   CSK_ABORT_RPL_PENDING,  /* expecting an abort reply */
+   CSK_CLOSE_CON_REQUESTED,/* we've sent a close_conn_req */
+   CSK_TX_DATA_SENT,   /* sent a TX_DATA WR on this connection */
+   CSK_TX_FAILOVER,/* Tx traffic failing over */
+   CSK_UPDATE_RCV_WND, /* Need to update rcv window */
+   CSK_RST_ABORTED,/* outgoing RST was aborted */
+   CSK_TLS_HANDSHK,/* TLS Handshake */
+};
+
+struct listen_ctx {
+   struct sock *lsk;
+   struct chtls_dev *cdev;
+   u32 state;
+};
+
+struct key_map {
+   unsigned long *addr;
+   unsigned int start;
+   unsigned int available;
+   unsigned int size;
+   spinlock_t lock; /* lock for key id request from map */
+} __packed;
+
+struct tls_scmd {
+   __be32 seqno_numivs;
+   __be32 ivgen_hdrlen;
+};
+
+struct chtls_dev {
+   struct tls_device tlsdev;
+   struct list_head list;
+   struct cxgb4_lld_info *lldi;
+   struct pci_dev *pdev;
+   struct listen_info *listen_hash_tab[LISTEN_INFO_HASH_SIZE];
+   spinlock_t listen_lock; /* lock for listen list */
+   struct net_device **ports;
+   struct tid_info *tids;
+   unsigned int pfvf;
+   const unsigned short *mtus;
+
+   spinlock_t aidr_lock cacheline_aligned_in_smp;
+   struct idr aidr; /* ATID id space */
+   struct idr hwtid_idr;
+   struct idr stid_idr;
+
+   spinlock_t idr_lock cacheline_aligned_in_smp;
+
+   struct net_device *egr_dev[NCHAN * 2];
+   struct sk_buff *rspq_skb_cache[1 << RSPQ_HASH_BITS];
+   struct sk_buff *askb;
+
+   struct sk_buff_head deferq;
+   struct work_struct deferq_task;
+
+   struct list_head list_node;
+   struct list_head rcu_node;
+   struct list_head na_node;
+   unsigned int send_page_order;
+   struct key_map kmap;
+};
+
+struct 

[Crypto v5 03/12] support for inline tls

2018-02-14 Thread Atul Gupta
Facility to register Inline TLS drivers to net/tls. Setup
TLS_FULL_HW prot to listen on offload device.

Cases handled
1. Inline TLS device exists, setup prot for TLS_FULL_HW
2. Atleast one Inline TLS exists, sets TLS_FULL_HW. If
non-inline capable device establish connection, move to TLS_SW_TX
3. default mode TLS_SW_TX continues

Signed-off-by: Atul Gupta 
---
 net/tls/tls_main.c | 124 ++---
 1 file changed, 117 insertions(+), 7 deletions(-)

diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c
index e07ee3a..81c61e9 100644
--- a/net/tls/tls_main.c
+++ b/net/tls/tls_main.c
@@ -38,6 +38,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -45,13 +46,9 @@
 MODULE_DESCRIPTION("Transport Layer Security Support");
 MODULE_LICENSE("Dual BSD/GPL");
 
-enum {
-   TLS_BASE_TX,
-   TLS_SW_TX,
-   TLS_NUM_CONFIG,
-};
-
-static struct proto tls_prots[TLS_NUM_CONFIG];
+static LIST_HEAD(device_list);
+static DEFINE_MUTEX(device_mutex);
+struct proto tls_prots[TLS_NUM_CONFIG];
 
 static inline void update_sk_prot(struct sock *sk, struct tls_context *ctx)
 {
@@ -260,6 +257,38 @@ static void tls_sk_proto_close(struct sock *sk, long 
timeout)
sk_proto_close(sk, timeout);
 }
 
+static struct net_device *get_netdev(struct sock *sk)
+{
+   struct inet_sock *inet = inet_sk(sk);
+   struct net_device *netdev = NULL;
+
+   netdev = dev_get_by_index(sock_net(sk), inet->cork.fl.flowi_oif);
+   return netdev;
+}
+
+static int get_tls_offload_dev(struct sock *sk)
+{
+   struct net_device *netdev;
+   struct tls_device *dev;
+   int rc = -EINVAL;
+
+   netdev = get_netdev(sk);
+   if (!netdev)
+   goto out;
+
+   mutex_lock(_mutex);
+   list_for_each_entry(dev, _list, dev_list) {
+   if (dev->netdev && dev->netdev(dev, netdev)) {
+   rc = 0;
+   break;
+   }
+   }
+   mutex_unlock(_mutex);
+   dev_put(netdev);
+out:
+   return rc;
+}
+
 static int do_tls_getsockopt_tx(struct sock *sk, char __user *optval,
int __user *optlen)
 {
@@ -401,6 +430,15 @@ static int do_tls_setsockopt_tx(struct sock *sk, char 
__user *optval,
goto out;
}
 
+   rc = get_tls_offload_dev(sk);
+   if (rc) {
+   goto out;
+   } else {
+   /* Retain HW unhash for cleanup and move to SW Tx */
+   sk->sk_prot[TLS_BASE_TX].unhash =
+   sk->sk_prot[TLS_FULL_HW].unhash;
+   }
+
/* currently SW is default, we will have ethtool in future */
rc = tls_set_sw_offload(sk, ctx);
tx_conf = TLS_SW_TX;
@@ -448,6 +486,54 @@ static int tls_setsockopt(struct sock *sk, int level, int 
optname,
return do_tls_setsockopt(sk, optname, optval, optlen);
 }
 
+static int tls_hw_prot(struct sock *sk)
+{
+   struct tls_context *ctx = tls_get_ctx(sk);
+   struct tls_device *dev;
+
+   mutex_lock(_mutex);
+   list_for_each_entry(dev, _list, dev_list) {
+   if (dev->feature && dev->feature(dev)) {
+   ctx->tx_conf = TLS_FULL_HW;
+   update_sk_prot(sk, ctx);
+   break;
+   }
+   }
+   mutex_unlock(_mutex);
+   return ctx->tx_conf;
+}
+
+static void tls_hw_unhash(struct sock *sk)
+{
+   struct tls_device *dev;
+
+   mutex_lock(_mutex);
+   list_for_each_entry(dev, _list, dev_list) {
+   if (dev->unhash)
+   dev->unhash(dev, sk);
+   }
+   mutex_unlock(_mutex);
+   tcp_prot.unhash(sk);
+}
+
+static int tls_hw_hash(struct sock *sk)
+{
+   struct tls_device *dev;
+   int err;
+
+   err = tcp_prot.hash(sk);
+   mutex_lock(_mutex);
+   list_for_each_entry(dev, _list, dev_list) {
+   if (dev->hash)
+   err |= dev->hash(dev, sk);
+   }
+   mutex_unlock(_mutex);
+
+   if (err)
+   tls_hw_unhash(sk);
+   return err;
+}
+
 static int tls_init(struct sock *sk)
 {
struct inet_connection_sock *icsk = inet_csk(sk);
@@ -466,6 +552,9 @@ static int tls_init(struct sock *sk)
ctx->sk_proto_close = sk->sk_prot->close;
 
ctx->tx_conf = TLS_BASE_TX;
+   if (tls_hw_prot(sk) == TLS_FULL_HW)
+   goto out;
+
update_sk_prot(sk, ctx);
 out:
return rc;
@@ -487,7 +576,27 @@ static void build_protos(struct proto *prot, struct proto 
*base)
prot[TLS_SW_TX] = prot[TLS_BASE_TX];
prot[TLS_SW_TX].sendmsg = tls_sw_sendmsg;
prot[TLS_SW_TX].sendpage= tls_sw_sendpage;
+
+   prot[TLS_FULL_HW] = prot[TLS_BASE_TX];
+   prot[TLS_FULL_HW].hash  = tls_hw_hash;
+   prot[TLS_FULL_HW].unhash= tls_hw_unhash;
+}
+
+void tls_register_device(struct tls_device *device)
+{
+   

[Crypto v5 00/12] Chelsio Inline TLS

2018-02-14 Thread Atul Gupta
Series for Chelsio Inline TLS driver (chtls.ko)

Driver use the ULP infrastructure to register chtls as Inline TLS ULP.
Chtls use TCP Sockets to transmit and receive TLS record. TCP proto_ops
is extended to offload TLS record.

T6 adapter provides the following features:
-TLS record offload, TLS header, encrypt, digest and transmit
-TLS record receive and decrypt
-TLS keys store
-TCP/IP engine
-TLS engine
-GCM crypto engine [support CBC also]

TLS provides security at the transport layer. It uses TCP to provide
reliable end-to-end transport of application data. It relies on TCP
for any retransmission. TLS session comprises of three parts:
a. TCP/IP connection
b. TLS handshake
c. Record layer processing

TLS handshake state machine is executed in host (refer standard
implementation eg. OpenSSL).  Setsockopt [SOL_TCP, TCP_ULP] initialize
TCP proto-ops for Chelsio inline tls support. setsockopt(sock, SOL_TCP,
TCP_ULP, "tls", sizeof("tls"));

Tx and Rx Keys are decided during handshake and programmed onto the chip
after CCS is exchanged.
struct tls12_crypto_info_aes_gcm_128 crypto_info
setsockopt(sock, SOL_TLS, TLS_TX, _info, sizeof(crypto_info))
Finish is the first encrypted/decrypted message tx/rx inline.

On the Tx path TLS engine receive plain text from openssl, insert IV,
fetches the tx key, create cipher text records and generate MAC. TLS
header is added to cipher text and forward to TCP/IP engine for transport
layer processing and transmission on wire.
TX:
Application--openssl--chtls---TLS engine---encrypt/auth---TCP/IP
engine---wire.

On the Rx side, data received is PDU aligned at record
boundaries. TLS processes only the complete record. If rx key is programmed
on CCS receive, data is decrypted and plain text is posted to host.
RX:
Wire--cipher-text--TCP/IP engine [PDU align]---TLS engine---
decrypt/auth---plain-text--chtls--openssl--application

v5: set TLS_FULL_HW for registered inline tls drivers
   -set TLS_FULL_HW prot for offload connection else move
to TLS_SW_TX
   -Case handled for interface with same IP [David Miller]
   -Removed Specific IP and INADDR_ANY handling [v4]

v4: removed chtls ULP type, retained tls ULP
   -registered chtls with net tls
   -defined struct tls_device to register the Inline drivers
   -ethtool interface tls-inline to enable Inline TLS for interface
   -prot update to support inline TLS

v3: fixed the kbuild test issues
   -made few funtions static
   -initialized few variables

v2: fixed the following based on the review comments of Stephan Mueller,
Stefano Brivio and Hannes Frederic
-Added more details in cover letter
-Fixed indentation and formating issues
-Using aes instead of aes-generic
-memset key info after programing the key on chip
-reordered the patch sequence

Atul Gupta (12):
  tls: tls_device struct to register TLS drivers
  ethtool: feature for Inline TLS in HW
  support for inline tls
  chtls: structure and macro definiton
  cxgb4: Inline TLS FW Interface
  cxgb4: LLD driver changes to enable TLS
  chcr: Key Macro
  chtls: Key program
  chtls: CPL handler definition
  chtls: Inline crypto request Tx/Rx
  chtls: Register the chtls Inline TLS with net tls
  Makefile Kconfig

 drivers/crypto/chelsio/Kconfig |   11 +
 drivers/crypto/chelsio/Makefile|1 +
 drivers/crypto/chelsio/chcr_algo.h |   42 +
 drivers/crypto/chelsio/chcr_core.h |   55 +-
 drivers/crypto/chelsio/chtls/Makefile  |4 +
 drivers/crypto/chelsio/chtls/chtls.h   |  487 +
 drivers/crypto/chelsio/chtls/chtls_cm.c| 2046 
 drivers/crypto/chelsio/chtls/chtls_cm.h|  203 ++
 drivers/crypto/chelsio/chtls/chtls_hw.c|  394 
 drivers/crypto/chelsio/chtls/chtls_io.c| 1867 ++
 drivers/crypto/chelsio/chtls/chtls_main.c  |  574 ++
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c |   18 +-
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c|   32 +-
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h |7 +
 drivers/net/ethernet/chelsio/cxgb4/sge.c   |   98 +-
 drivers/net/ethernet/chelsio/cxgb4/t4_msg.h|  121 +-
 drivers/net/ethernet/chelsio/cxgb4/t4_regs.h   |2 +
 drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h  |  165 +-
 include/linux/netdev_features.h|2 +
 include/net/tls.h  |   24 +
 include/uapi/linux/tls.h   |1 +
 net/core/ethtool.c |1 +
 net/ipv4/tcp_minisocks.c   |1 +
 net/tls/tls_main.c |  124 +-
 24 files changed, 6254 insertions(+), 26 deletions(-)
 create mode 100644 drivers/crypto/chelsio/chtls/Makefile
 create mode 100644 drivers/crypto/chelsio/chtls/chtls.h
 create mode 100644 

[PATCH bpf 2/2] tools: bpftool: preserve JSON output on errors on batch file parsing

2018-02-14 Thread Jakub Kicinski
From: Quentin Monnet 

Before this patch, perror() function is used in some cases when bpftool
fails to parse its input file in batch mode. This function does not
integrate well with the rest of the output when JSON is used, so we
replace it by something that is compliant.

Most calls to perror() had already been replaced in a previous patch,
this one is a leftover.

Fixes: d319c8e101c5 ("tools: bpftool: preserve JSON output on errors on batch 
file parsing")
Signed-off-by: Quentin Monnet 
Acked-by: Jakub Kicinski 
---
 tools/bpf/bpftool/main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/bpf/bpftool/main.c b/tools/bpf/bpftool/main.c
index 3a0396d87c42..185acfa229b5 100644
--- a/tools/bpf/bpftool/main.c
+++ b/tools/bpf/bpftool/main.c
@@ -244,7 +244,7 @@ static int do_batch(int argc, char **argv)
}
 
if (errno && errno != ENOENT) {
-   perror("reading batch file failed");
+   p_err("reading batch file failed: %s", strerror(errno));
err = -1;
} else {
p_info("processed %d lines", lines);
-- 
2.15.1



[PATCH bpf 0/2] tools: bpftool: minor fixes for JSON in batch mode

2018-02-14 Thread Jakub Kicinski
Quentin says:

These are two minor fixes to avoid breaking JSON output in batch mode. The
first one makes bpftool output a "null" JSON object, as expected in batch
mode if nothing else is to be printed, when dumping program instructions
into an output file. The second one replaces a call to "perror()" with
something that does not break JSON when parsing input file for batch mode.

Quentin Monnet (2):
  tools: bpftool: preserve JSON for batch mode when dumping insns to
file
  tools: bpftool: preserve JSON output on errors on batch file parsing

 tools/bpf/bpftool/main.c | 2 +-
 tools/bpf/bpftool/prog.c | 3 +++
 2 files changed, 4 insertions(+), 1 deletion(-)

-- 
2.15.1



[PATCH bpf 1/2] tools: bpftool: preserve JSON for batch mode when dumping insns to file

2018-02-14 Thread Jakub Kicinski
From: Quentin Monnet 

Print a "null" JSON object to standard output when bpftool is used to
print program instructions to a file, so as to avoid breaking JSON
output on batch mode.

This null object was added for most commands in a previous commit, but
this specific case had been omitted.

Fixes: 004b45c0e51a ("tools: bpftool: provide JSON output for all possible 
commands")
Signed-off-by: Quentin Monnet 
Acked-by: Jakub Kicinski 
---
 tools/bpf/bpftool/prog.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c
index e8e2baaf93c2..e549e329be82 100644
--- a/tools/bpf/bpftool/prog.c
+++ b/tools/bpf/bpftool/prog.c
@@ -774,6 +774,9 @@ static int do_dump(int argc, char **argv)
  n < 0 ? strerror(errno) : "short write");
goto err_free;
}
+
+   if (json_output)
+   jsonw_null(json_wtr);
} else {
if (member_len == _prog_len) {
const char *name = NULL;
-- 
2.15.1



Re: [PATCH net-next 0/3] eBPF Seccomp filters

2018-02-14 Thread Alexei Starovoitov
On Wed, Feb 14, 2018 at 10:32:22AM -0700, Tycho Andersen wrote:
> > >
> > > What's the reason for adding eBPF support? seccomp shouldn't need it,
> > > and it only makes the code more complex. I'd rather stick with cBPF
> > > until we have an overwhelmingly good reason to use eBPF as a "native"
> > > seccomp filter language.
> > >
> > 
> > I can think of two fairly strong use cases for eBPF's ability to call
> > functions: logging and Tycho's user notifier thing.
> 
> Worth noting that there is one additional thing that I didn't
> implement, but which would be nice and is probably not possible with
> eBPF (at least, not without a bunch of additional infrastructure):
> passing fds back to the tracee from the manager if you intercept
> socket(), or accept() or something.
> 
> This could again be accomplished via other means, though it would be a
> lot nicer to have a primitive for it.

there is bpf_perf_event_output() interface that allows to stream
arbitrary data from kernel into user space via perf ring buffer.
User space can epoll on it. We use this in both tracing and networking
for notifications and streaming data transfers.
I suspect this can be used for 'logging' too, since it's cheap and fast.

Specifically for android we added bpf_lsm hooks, cookie/uid helpers,
and read-only maps.
Lorenzo,
there was a claim in this thread that bpf is disabled on android.
Can you please clarify ?
If it's actually disabled and there is no intent to enable it,
I'd rather not add any more android specific features to bpf.

What I think is important to understand is that BPF goes through
very active development. The verifier is constantly getting smarter.
There is work to add bounded loops, lock/unlock, get/put tracking,
global/percpu variables, dynamic linking and so on.
Most of the features are available to root only and unpriv
has very limited set. Like getting bpf_perf_event_output() to work
for unpriv will likely require additional verifier work.

So all cool bits will not be usable by seccomp+eBPF and unpriv
on day one. It's not a lot of work either, but once it's done
I'd hate to see arguments against adding more verifier features
just because eBPF is used by seccomp/landlock/other_security_thing.

Also I think the argument that seccomp+eBPF will be faster than
seccomp+cBPF is a weak one. I bet kpti on/off makes no difference
under seccomp, since _all_ syscalls are already slow for sandboxed app.
Instead of making seccomp 5% faster with eBPF, I think it's
worth looking into extending LSM hooks to cover all syscalls and
have programmable (bpf or whatever) filtering applied per syscall.
Like we can have a white list syscall table covered by lsm hooks
and any other syscall will get into old seccomp-style
filtering category automatically.
lsm+bpf would need to follow process hierarchy. It shouldn't be
a runtime check at syscall entry either, but compile time
extra branch in SYSCALL_DEFINE for non-whitelisted syscalls.
There are bunch of other things to figure out, but I think
the perf win will be bigger than replacing cBPF with eBPF in
existing seccomp.



Re: [PATCH iproute2 0/7] Add support for devlink resource abstraction

2018-02-14 Thread David Ahern
On 2/14/18 1:55 AM, Arkadi Sharshevsky wrote:
> Add support for devlink resource abstraction.
> 
> Arkadi Sharshevsky (7):
>   devlink: Change empty line indication with indentations
>   devlink: mnlg: Add support for extended ack
>   devlink: Add support for devlink resource abstraction
>   devlink: Add support for hot reload
>   devlink: Move dpipe context from heap to stack
>   devlink: Add support for resource/dpipe relation
>   devlink: Update man pages and add resource man
> 
>  devlink/devlink.c   | 774 
> 
>  devlink/mnlg.c  |  53 ++-
>  include/libnetlink.h|   1 +
>  include/list.h  |   5 +
>  lib/libnetlink.c|   4 +-
>  man/man8/devlink-dev.8  |  15 +
>  man/man8/devlink-resource.8 |  78 +
>  man/man8/devlink.8  |   1 +
>  8 files changed, 871 insertions(+), 60 deletions(-)
>  create mode 100644 man/man8/devlink-resource.8
> 

Looks ok to me.


RE: [Intel-wired-lan] [PATCH net-queue 3/3] e1000e: Avoid missed interrupts following ICR read.

2018-02-14 Thread Brown, Aaron F
> From: Intel-wired-lan [mailto:intel-wired-lan-boun...@osuosl.org] On
> Behalf Of Benjamin Poirier
> Sent: Wednesday, February 7, 2018 10:47 PM
> To: Kirsher, Jeffrey T 
> Cc: netdev@vger.kernel.org; intel-wired-...@lists.osuosl.org; linux-
> ker...@vger.kernel.org
> Subject: [Intel-wired-lan] [PATCH net-queue 3/3] e1000e: Avoid missed
> interrupts following ICR read.
> 
> The 82574 specification update errata 12 states that interrupts may be
> missed if ICR is read while INT_ASSERTED is not set. Avoid that problem by
> setting all bits related to events that can trigger the Other interrupt in
> IMS.
> 
> The Other interrupt is raised for such events regardless of whether or not
> they are set in IMS. However, only when they are set is the INT_ASSERTED
> bit also set in ICR.
> 
> By doing this, we ensure that INT_ASSERTED is always set when we read ICR
> in e1000_msix_other() and steer clear of the errata. This also ensures that
> ICR will automatically be cleared on read, therefore we no longer need to
> clear bits explicitly.
> 
> Signed-off-by: Benjamin Poirier 
> ---
>  drivers/net/ethernet/intel/e1000e/defines.h | 21
> -
>  drivers/net/ethernet/intel/e1000e/netdev.c  | 11 ---
>  2 files changed, 24 insertions(+), 8 deletions(-)
> 

Tested-by: Aaron Brown 


RE: [Intel-wired-lan] [PATCH net-queue 1/3] Partial revert "e1000e: Avoid receiver overrun interrupt bursts"

2018-02-14 Thread Brown, Aaron F
> From: Intel-wired-lan [mailto:intel-wired-lan-boun...@osuosl.org] On
> Behalf Of Benjamin Poirier
> Sent: Wednesday, February 7, 2018 10:47 PM
> To: Kirsher, Jeffrey T 
> Cc: netdev@vger.kernel.org; intel-wired-...@lists.osuosl.org; linux-
> ker...@vger.kernel.org
> Subject: [Intel-wired-lan] [PATCH net-queue 1/3] Partial revert "e1000e:
> Avoid receiver overrun interrupt bursts"
> 
> This partially reverts commit 4aea7a5c5e940c1723add439f4088844cd26196d.
> 
> We keep the fix for the first part of the problem (1) described in the log
> of that commit, that is to read ICR in the other interrupt handler. We
> remove the fix for the second part of the problem (2), Other interrupt
> throttling.
> 
> Bursts of "Other" interrupts may once again occur during rxo (receive
> overflow) traffic conditions. This is deemed acceptable in the interest of
> avoiding unforeseen fallout from changes that are not strictly necessary.
> As discussed, the e1000e driver should be in "maintenance mode".
> 
> Link: https://www.spinics.net/lists/netdev/msg480675.html
> Signed-off-by: Benjamin Poirier 
> ---
>  drivers/net/ethernet/intel/e1000e/netdev.c | 16 ++--
>  1 file changed, 2 insertions(+), 14 deletions(-)

Tested-by: Aaron Brown 


RE: [Intel-wired-lan] [PATCH net-queue 2/3] e1000e: Fix queue interrupt re-raising in Other interrupt.

2018-02-14 Thread Brown, Aaron F
> From: Intel-wired-lan [mailto:intel-wired-lan-boun...@osuosl.org] On
> Behalf Of Benjamin Poirier
> Sent: Wednesday, February 7, 2018 10:47 PM
> To: Kirsher, Jeffrey T 
> Cc: netdev@vger.kernel.org; intel-wired-...@lists.osuosl.org; linux-
> ker...@vger.kernel.org
> Subject: [Intel-wired-lan] [PATCH net-queue 2/3] e1000e: Fix queue
> interrupt re-raising in Other interrupt.
> 
> restores the ICS write for rx/tx queue interrupts which was present before
> commit 16ecba59bc33 ("e1000e: Do not read ICR in Other interrupt",
> v4.5-rc1) but was not restored in commit 4aea7a5c5e94 ("e1000e: Avoid
> receiver overrun interrupt bursts", v4.15-rc1).
> 
> This re-raises the queue interrupts in case the txq or rxq bits were set in
> ICR and the Other interrupt handler read and cleared ICR before the queue
> interrupt was raised.
> 
> Fixes: 4aea7a5c5e94 ("e1000e: Avoid receiver overrun interrupt bursts")
> Signed-off-by: Benjamin Poirier 
> ---
>  drivers/net/ethernet/intel/e1000e/netdev.c | 3 +++
>  1 file changed, 3 insertions(+)

Tested-by: Aaron Brown 


Re: [Crypto v4 12/12] Makefile Kconfig

2018-02-14 Thread kbuild test robot
Hi Atul,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on cryptodev/master]
[cannot apply to net/master net-next/master v4.16-rc1 next-20180214]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Atul-Gupta/Chelsio-Inline-TLS/20180215-072600
base:   
https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git master
config: ia64-allmodconfig (attached as .config)
compiler: ia64-linux-gcc (GCC) 7.2.0
reproduce:
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=ia64 

All warnings (new ones prefixed by >>):

   drivers/crypto/chelsio/chtls/chtls_cm.c: In function 'chtls_rx_ack':
>> drivers/crypto/chelsio/chtls/chtls_cm.c:1979:4: warning: this 'if' clause 
>> does not guard... [-Wmisleading-indentation]
   if (csk->wr_nondata)
   ^~
   drivers/crypto/chelsio/chtls/chtls_cm.c:1981:5: note: ...this statement, but 
the latter is misleadingly indented as if it were guarded by the 'if'
break;
^

vim +/if +1979 drivers/crypto/chelsio/chtls/chtls_cm.c

763a7f5f Atul Gupta 2018-02-12  1961  
763a7f5f Atul Gupta 2018-02-12  1962  static void chtls_rx_ack(struct sock *sk, 
struct sk_buff *skb)
763a7f5f Atul Gupta 2018-02-12  1963  {
763a7f5f Atul Gupta 2018-02-12  1964struct cpl_fw4_ack *hdr = cplhdr(skb) + 
RSS_HDR;
763a7f5f Atul Gupta 2018-02-12  1965struct chtls_sock *csk = 
sk->sk_user_data;
763a7f5f Atul Gupta 2018-02-12  1966struct tcp_sock *tp = tcp_sk(sk);
763a7f5f Atul Gupta 2018-02-12  1967u32 snd_una = ntohl(hdr->snd_una);
763a7f5f Atul Gupta 2018-02-12  1968u8 credits = hdr->credits;
763a7f5f Atul Gupta 2018-02-12  1969  
763a7f5f Atul Gupta 2018-02-12  1970csk->wr_credits += credits;
763a7f5f Atul Gupta 2018-02-12  1971  
763a7f5f Atul Gupta 2018-02-12  1972if (csk->wr_unacked > 
csk->wr_max_credits - csk->wr_credits)
763a7f5f Atul Gupta 2018-02-12  1973csk->wr_unacked = 
csk->wr_max_credits - csk->wr_credits;
763a7f5f Atul Gupta 2018-02-12  1974  
763a7f5f Atul Gupta 2018-02-12  1975while (credits) {
763a7f5f Atul Gupta 2018-02-12  1976struct sk_buff *pskb = 
csk->wr_skb_head;
763a7f5f Atul Gupta 2018-02-12  1977  
763a7f5f Atul Gupta 2018-02-12  1978if (unlikely(!pskb)) {
763a7f5f Atul Gupta 2018-02-12 @1979if (csk->wr_nondata)
763a7f5f Atul Gupta 2018-02-12  1980csk->wr_nondata 
-= credits;
763a7f5f Atul Gupta 2018-02-12  1981break;
763a7f5f Atul Gupta 2018-02-12  1982}
763a7f5f Atul Gupta 2018-02-12  1983if (unlikely(credits < 
pskb->csum)) {
763a7f5f Atul Gupta 2018-02-12  1984pskb->csum -= credits;
763a7f5f Atul Gupta 2018-02-12  1985break;
763a7f5f Atul Gupta 2018-02-12  1986}
763a7f5f Atul Gupta 2018-02-12  1987dequeue_wr(sk);
763a7f5f Atul Gupta 2018-02-12  1988credits -= pskb->csum;
763a7f5f Atul Gupta 2018-02-12  1989kfree_skb(pskb);
763a7f5f Atul Gupta 2018-02-12  1990}
763a7f5f Atul Gupta 2018-02-12  1991if (hdr->seq_vld & 
CPL_FW4_ACK_FLAGS_SEQVAL) {
763a7f5f Atul Gupta 2018-02-12  1992if (unlikely(before(snd_una, 
tp->snd_una))) {
763a7f5f Atul Gupta 2018-02-12  1993kfree_skb(skb);
763a7f5f Atul Gupta 2018-02-12  1994return;
763a7f5f Atul Gupta 2018-02-12  1995}
763a7f5f Atul Gupta 2018-02-12  1996  
763a7f5f Atul Gupta 2018-02-12  1997if (tp->snd_una != snd_una) {
763a7f5f Atul Gupta 2018-02-12  1998tp->snd_una = snd_una;
763a7f5f Atul Gupta 2018-02-12  1999
dst_confirm(sk->sk_dst_cache);
763a7f5f Atul Gupta 2018-02-12  2000tp->rcv_tstamp = 
tcp_time_stamp(tp);
763a7f5f Atul Gupta 2018-02-12  2001if (tp->snd_una == 
tp->snd_nxt &&
763a7f5f Atul Gupta 2018-02-12  2002
!csk_flag_nochk(csk, CSK_TX_FAILOVER))
763a7f5f Atul Gupta 2018-02-12  2003
csk_reset_flag(csk, CSK_TX_WAIT_IDLE);
763a7f5f Atul Gupta 2018-02-12  2004}
763a7f5f Atul Gupta 2018-02-12  2005}
763a7f5f Atul Gupta 2018-02-12  2006  
763a7f5f Atul Gupta 2018-02-12  2007if (hdr->seq_vld & 
CPL_FW4_ACK_FLAGS_CH) {
763a7f5f Atul Gupta 2018-02-12  2008unsigned int fclen16 = 
roundup(failover_flowc_wr_len, 16);
763a7f5f Atul Gupta 2018-02-12  2009  
763a7f5f Atul Gupta 2018-02-12  2010csk->wr_credits -= fclen16;
763a7f5f Atul Gupta 2018-02-12  2011csk

Re: [PATCH 0/3] Remove IPVlan module dependencies on IPv6 and Netfilter

2018-02-14 Thread David Miller
From: Matteo Croce 
Date: Wed, 14 Feb 2018 19:13:42 +0100

> The IPVlan module currently depends on IPv6 and Netfilter.
> Refactor the code to allow building IPVlan module regardless of the value of
> CONFIG_IPV6 and CONFIG_NETFILTER.
> Also change the dependency to CONFIG_NET_L3_MASTER_DEV into a select,
> as compiling L3 Master device alone has no sense.

As stated, the L3 master and netfilter are hard depenencies when using
ipvlan in some modes.

You can't just ifdef the driver like this, it changes fundamental
pieces of functionality.

I would say leave things as they are right now.


Re: [PATCH V2 net-next 4/7] rds: support for zcopy completion notification

2018-02-14 Thread Willem de Bruijn
On Wed, Feb 14, 2018 at 5:28 AM, Sowmini Varadhan
 wrote:
> RDS removes a datagram (rds_message) from the retransmit queue when
> an ACK is received. The ACK indicates that the receiver has queued
> the RDS datagram, so that the sender can safely forget the datagram.
> When all references to the rds_message are quiesced, rds_message_purge
> is called to release resources used by the rds_message
>
> If the datagram to be removed had pinned pages set up, add
> an entry to the rs->rs_znotify_queue so that the notifcation
> will be sent up via rds_rm_zerocopy_callback() when the
> rds_message is eventually freed by rds_message_purge.
>
> rds_rm_zerocopy_callback() attempts to batch the number of cookies
> sent with each notification  to a max of SO_EE_ORIGIN_MAX_ZCOOKIES.
> This is achieved by checking the tail skb in the sk_error_queue:
> if this has room for one more cookie, the cookie from the
> current notification is added; else a new skb is added to the
> sk_error_queue. Every invocation of rds_rm_zerocopy_callback() will
> trigger a ->sk_error_report to notify the application.
>
> Signed-off-by: Sowmini Varadhan 
> ---

> +static void rds_rm_zerocopy_callback(struct rds_sock *rs,
> +struct rds_znotifier *znotif)
> +{
> +   struct sock *sk = rds_rs_to_sk(rs);
> +   struct sk_buff *skb, *tail;
> +   struct sock_exterr_skb *serr;
> +   unsigned long flags;
> +   struct sk_buff_head *q;
> +   u32 cookie = znotif->z_cookie;
> +
> +   q = >sk_error_queue;
> +   spin_lock_irqsave(>lock, flags);
> +   tail = skb_peek_tail(q);
> +
> +   if (tail && skb_zcookie_add(tail, cookie)) {
> +   spin_unlock_irqrestore(>lock, flags);
> +   mm_unaccount_pinned_pages(>z_mmp);
> +   consume_skb(rds_skb_from_znotifier(znotif));
> +   sk->sk_error_report(sk);
> +   return;
> +   }
> +
> +   skb = rds_skb_from_znotifier(znotif);
> +   serr = SKB_EXT_ERR(skb);
> +   serr->ee.ee_errno = 0;
> +   serr->ee.ee_origin = SO_EE_ORIGIN_ZCOOKIE;
> +   serr->ee.ee_info = 0;
> +   serr->ee.ee_code |= SO_EE_CODE_ZEROCOPY_COPIED;

One more thing: this code notifies that the operation succeeded, but
the data was copied in the process. It does not have to be set otherwise.


Re: [PATCH net-next v2] selftests/net: fixes psock_fanout eBPF test case

2018-02-14 Thread Willem de Bruijn
On Wed, Feb 14, 2018 at 7:19 PM, Prashant Bhole
 wrote:
> eBPF test fails due to verifier failure because log_buf is too small.
> Fixed by increasing log_buf size
>
> Signed-off-by: Prashant Bhole 

Acked-by: Willem de Bruijn 

Thanks Prashant.


[PATCH net-next v2] selftests/net: fixes psock_fanout eBPF test case

2018-02-14 Thread Prashant Bhole
eBPF test fails due to verifier failure because log_buf is too small.
Fixed by increasing log_buf size

Signed-off-by: Prashant Bhole 
---
v2: log_buf is statically allocated

 tools/testing/selftests/net/psock_fanout.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/net/psock_fanout.c 
b/tools/testing/selftests/net/psock_fanout.c
index 989f917068d1..d4346b16b2c1 100644
--- a/tools/testing/selftests/net/psock_fanout.c
+++ b/tools/testing/selftests/net/psock_fanout.c
@@ -128,6 +128,8 @@ static void sock_fanout_getopts(int fd, uint16_t 
*typeflags, uint16_t *group_id)
 
 static void sock_fanout_set_ebpf(int fd)
 {
+   static char log_buf[65536];
+
const int len_off = __builtin_offsetof(struct __sk_buff, len);
struct bpf_insn prog[] = {
{ BPF_ALU64 | BPF_MOV | BPF_X,   6, 1, 0, 0 },
@@ -140,7 +142,6 @@ static void sock_fanout_set_ebpf(int fd)
{ BPF_ALU   | BPF_MOV | BPF_K,   0, 0, 0, 0 },
{ BPF_JMP   | BPF_EXIT,  0, 0, 0, 0 }
};
-   char log_buf[512];
union bpf_attr attr;
int pfd;
 
-- 
2.13.6




Re: [PATCH V2 net-next 0/7] RDS: zerocopy support

2018-02-14 Thread Willem de Bruijn
On Wed, Feb 14, 2018 at 5:28 AM, Sowmini Varadhan
 wrote:
> This is version 2 of the series at
>   https://www.mail-archive.com/netdev@vger.kernel.org/msg213829.html
>
> Review comments addressed
> Patch 4:
>   - make sure to always sock_put m_rs even if there is no znotifier.
>   - major rewrite of notification, resulting in much simplification.
>
> Patch 5:
>   - remove unused data_len argument to rds_rm_size;
>   - unmap as necessary if we fail in the middle of zerocopy setup
>
> Patch 7:
>   - restructured do_recv_completion to avoid excessive code re-indent
>   - on-stack allocation of cmsghdr for cookie in do_sendmsg
>   - Additional verification: Verify ncookies <= MAX_.., verify ret ==
> ncookies * sizeof(uint32_t)
>
> A brief overview of this feature follows.
>
> This patch series provides support for MSG_ZERCOCOPY
> on a PF_RDS socket based on the APIs and infrastructure added
> by f214f915e7db ("tcp: enable MSG_ZEROCOPY")
>
> For single threaded rds-stress testing using rds-tcp with the
> ixgbe driver using 1M message sizes (-a 1M -q 1M) preliminary
> results show that  there is a significant reduction in latency: about
> 90 usec with zerocopy, compared with 200 usec without zerocopy.
>
> This patchset modifies the above for zerocopy in the following manner.
> - if the MSG_ZEROCOPY flag is specified with rds_sendmsg(), and,
> - if the SO_ZEROCOPY  socket option has been set on the PF_RDS socket,
> application pages sent down with rds_sendmsg are pinned. The pinning
> uses the accounting infrastructure added by a91dbff551a6 ("sock: ulimit
> on MSG_ZEROCOPY pages"). The message is unpinned when all references
> to the message go down to 0, and the message is freed by rds_message_purge.
>
> A multithreaded application using this infrastructure must send down
> a unique 32 bit cookie as ancillary data with each sendmsg invocation.
> The format of this ancillary data is described in Patch 5 of the series.
> The cookie is passed up to the application on the sk_error_queue when
> the message is unpinned, indicating to the application that it is now
> safe to free/reuse the message buffer. The details of the completion
> notifiction are provided in Patch 4 of this series.
>
>
> Sowmini Varadhan (7):
>   skbuff: export mm_[un]account_pinned_pages for other modules
>   rds: hold a sock ref from rds_message to the rds_sock
>   sock: permit SO_ZEROCOPY on PF_RDS socket
>   rds: support for zcopy completion notification
>   rds: zerocopy Tx support.
>   selftests/net: add support for PF_RDS sockets
>   selftests/net: add zerocopy support for PF_RDS test case
>
>  include/linux/skbuff.h |3 +
>  include/uapi/linux/errqueue.h  |2 +
>  include/uapi/linux/rds.h   |1 +
>  net/core/skbuff.c  |6 +-
>  net/core/sock.c|   25 +++---
>  net/rds/af_rds.c   |2 +
>  net/rds/message.c  |  132 ++-
>  net/rds/rds.h  |   17 -
>  net/rds/recv.c |2 +
>  net/rds/send.c |   51 ---
>  tools/testing/selftests/net/msg_zerocopy.c |  133 ++-
>  11 files changed, 339 insertions(+), 35 deletions(-)
>

A few inline suggestions in patch 5/7 were already discussed in that thread.
These will be cleaned up in a follow-on patch.

The fragile use of skb->cb[] in patch 4/7 should also be addressed there.

With that caveat, for the series:

Acked-by: Willem de Bruijn 


Re: [PATCH V2 net-next 4/7] rds: support for zcopy completion notification

2018-02-14 Thread Santosh Shilimkar

On 2/14/2018 2:26 PM, Willem de Bruijn wrote:

On Wed, Feb 14, 2018 at 1:50 PM, Santosh Shilimkar


[...]


This error change might need to go though other subsystem tree. May
be you can seperate it and also copy "linux-...@vger.kernel.org"


Previous changes to this file also went in through net-next, so this is
fine. The error queue is a socket, so network, datastructure.


OK if that acceptable then there is no need to split the change.


As for naming, zerocopy is unfortunately an overused term. I did not
help matters when adding msg_zerocopy. 

:-)


That said, let's try to keep
consistent naming across socket families, so no zmsg prefix only in
RDS.
Fair enough.


Regards,
Santosh


Re: [PATCH V2 net-next 5/7] rds: zerocopy Tx support.

2018-02-14 Thread Willem de Bruijn
On Wed, Feb 14, 2018 at 7:09 PM, Sowmini Varadhan
 wrote:
> On (02/14/18 18:48), Willem de Bruijn wrote:
>>
>> If the missing break is intentional, no need to respin just for the other
>> minor comments.
>
> yes the missing break is intentional-  the function returns the
> size of the scatterlist needed for RDMA, and RDS_CMSG_ZCOPY_COOKIE
> (like RDMA_DEST and RDMA_MAP) is meta-data that does not change
> that size.
>
> I expect to be in the neighborhood of this  code pretty soon, to get
> the additional opimization of passing up the zcopy completion
> as part of recvmsg (see the discussion in
> https://www.mail-archive.com/netdev@vger.kernel.org/msg212788.html)
>
> I can take care of the other code-cleanup comment suggestions in
> here at that time..

Sounds good.


Re: [PATCH V2 net-next 4/7] rds: support for zcopy completion notification

2018-02-14 Thread Willem de Bruijn
On Wed, Feb 14, 2018 at 5:28 AM, Sowmini Varadhan
 wrote:
> RDS removes a datagram (rds_message) from the retransmit queue when
> an ACK is received. The ACK indicates that the receiver has queued
> the RDS datagram, so that the sender can safely forget the datagram.
> When all references to the rds_message are quiesced, rds_message_purge
> is called to release resources used by the rds_message
>
> If the datagram to be removed had pinned pages set up, add
> an entry to the rs->rs_znotify_queue so that the notifcation
> will be sent up via rds_rm_zerocopy_callback() when the
> rds_message is eventually freed by rds_message_purge.
>
> rds_rm_zerocopy_callback() attempts to batch the number of cookies
> sent with each notification  to a max of SO_EE_ORIGIN_MAX_ZCOOKIES.
> This is achieved by checking the tail skb in the sk_error_queue:
> if this has room for one more cookie, the cookie from the
> current notification is added; else a new skb is added to the
> sk_error_queue. Every invocation of rds_rm_zerocopy_callback() will
> trigger a ->sk_error_report to notify the application.
>
> Signed-off-by: Sowmini Varadhan 
> ---

> +static void rds_rm_zerocopy_callback(struct rds_sock *rs,
> +struct rds_znotifier *znotif)
> +{
> +   struct sock *sk = rds_rs_to_sk(rs);
> +   struct sk_buff *skb, *tail;
> +   struct sock_exterr_skb *serr;
> +   unsigned long flags;
> +   struct sk_buff_head *q;
> +   u32 cookie = znotif->z_cookie;
> +
> +   q = >sk_error_queue;
> +   spin_lock_irqsave(>lock, flags);
> +   tail = skb_peek_tail(q);
> +
> +   if (tail && skb_zcookie_add(tail, cookie)) {
> +   spin_unlock_irqrestore(>lock, flags);
> +   mm_unaccount_pinned_pages(>z_mmp);
> +   consume_skb(rds_skb_from_znotifier(znotif));
> +   sk->sk_error_report(sk);
> +   return;
> +   }
> +
> +   skb = rds_skb_from_znotifier(znotif);
> +   serr = SKB_EXT_ERR(skb);
> +   serr->ee.ee_errno = 0;
> +   serr->ee.ee_origin = SO_EE_ORIGIN_ZCOOKIE;
> +   serr->ee.ee_info = 0;
> +   serr->ee.ee_code |= SO_EE_CODE_ZEROCOPY_COPIED;

This resets selective fields in skb->cb[]. That array was previously used
as struct rds_znotifier, so may have non-zero state left over. Due to length
of serr->header it is likely that notifier and serr->ee do not overlap. But if
they do kernel data is leaked to userspace. And size of rds_znotifier may
change, so relying on that is fragile. Safer to clear serr->ee completely.


Re: [PATCH V2 net-next 5/7] rds: zerocopy Tx support.

2018-02-14 Thread Sowmini Varadhan
On (02/14/18 18:48), Willem de Bruijn wrote:
> 
> If the missing break is intentional, no need to respin just for the other
> minor comments.

yes the missing break is intentional-  the function returns the
size of the scatterlist needed for RDMA, and RDS_CMSG_ZCOPY_COOKIE
(like RDMA_DEST and RDMA_MAP) is meta-data that does not change
that size.

I expect to be in the neighborhood of this  code pretty soon, to get
the additional opimization of passing up the zcopy completion
as part of recvmsg (see the discussion in
https://www.mail-archive.com/netdev@vger.kernel.org/msg212788.html)
 
I can take care of the other code-cleanup comment suggestions in
here at that time..

--Sowmini


Re: [PATCH V2 net-next 5/7] rds: zerocopy Tx support.

2018-02-14 Thread Willem de Bruijn
On Wed, Feb 14, 2018 at 5:28 AM, Sowmini Varadhan
 wrote:
> If the MSG_ZEROCOPY flag is specified with rds_sendmsg(), and,
> if the SO_ZEROCOPY socket option has been set on the PF_RDS socket,
> application pages sent down with rds_sendmsg() are pinned.
>
> The pinning uses the accounting infrastructure added by
> Commit a91dbff551a6 ("sock: ulimit on MSG_ZEROCOPY pages")
>
> The payload bytes in the message may not be modified for the
> duration that the message has been pinned. A multi-threaded
> application using this infrastructure may thus need to be notified
> about send-completion so that it can free/reuse the buffers
> passed to rds_sendmsg(). Notification of send-completion will
> identify each message-buffer by a cookie that the application
> must specify as ancillary data to rds_sendmsg().
> The ancillary data in this case has cmsg_level == SOL_RDS
> and cmsg_type == RDS_CMSG_ZCOPY_COOKIE.
>
> Signed-off-by: Sowmini Varadhan 
> ---

If the missing break is intentional, no need to respin just for the other
minor comments.

> @@ -341,12 +341,14 @@ struct rds_message *rds_message_map_pages(unsigned long 
> *page_addrs, unsigned in
> return rm;
>  }
>
> -int rds_message_copy_from_user(struct rds_message *rm, struct iov_iter *from)
> +int rds_message_copy_from_user(struct rds_message *rm, struct iov_iter *from,
> +  bool zcopy)
>  {
> unsigned long to_copy, nbytes;
> unsigned long sg_off;
> struct scatterlist *sg;
> int ret = 0;
> +   int length = iov_iter_count(from);
>
> rm->m_inc.i_hdr.h_len = cpu_to_be32(iov_iter_count(from));
>
> @@ -356,6 +358,53 @@ int rds_message_copy_from_user(struct rds_message *rm, 
> struct iov_iter *from)
> sg = rm->data.op_sg;
> sg_off = 0; /* Dear gcc, sg->page will be null from kzalloc. */
>
> +   if (zcopy) {
> +   int total_copied = 0;
> +   struct sk_buff *skb;
> +
> +   skb = alloc_skb(SO_EE_ORIGIN_MAX_ZCOOKIES * sizeof(u32),
> +   GFP_KERNEL);
> +   if (!skb)
> +   return -ENOMEM;
> +   rm->data.op_mmp_znotifier = RDS_ZCOPY_SKB(skb);
> +   memset(rm->data.op_mmp_znotifier, 0,
> +  sizeof(*rm->data.op_mmp_znotifier));

Not strictly needed, as alloc_skb clears skb->cb[]

> +   if (mm_account_pinned_pages(>data.op_mmp_znotifier->z_mmp,
> +   length)) {
> +   consume_skb(skb);
> +   rm->data.op_mmp_znotifier = NULL;
> +   return -ENOMEM;
> +   }

One less action to revert if moving the mm_account_pinned_pages check
before assigning op_mmp_znotifier.

Conversely, move to an err: label at the end to be able to deduplicate
with the error branch introduced below.

> @@ -875,12 +875,13 @@ static int rds_send_queue_rm(struct rds_sock *rs, 
> struct rds_connection *conn,
>   * rds_message is getting to be quite complicated, and we'd like to allocate
>   * it all in one go. This figures out how big it needs to be up front.
>   */
> -static int rds_rm_size(struct msghdr *msg, int data_len)
> +static int rds_rm_size(struct msghdr *msg, int num_sgs)
>  {
> struct cmsghdr *cmsg;
> int size = 0;
> int cmsg_groups = 0;
> int retval;
> +   bool zcopy_cookie = false;
>
> for_each_cmsghdr(cmsg, msg) {
> if (!CMSG_OK(msg, cmsg))
> @@ -899,6 +900,8 @@ static int rds_rm_size(struct msghdr *msg, int data_len)
>
> break;
>
> +   case RDS_CMSG_ZCOPY_COOKIE:
> +   zcopy_cookie = true;

break, or if intended to fall through, please label as such.

> case RDS_CMSG_RDMA_DEST:
> case RDS_CMSG_RDMA_MAP:
> cmsg_groups |= 2;


[PATCH] NFC: llcp: Limit size of SDP URI

2018-02-14 Thread Kees Cook
The tlv_len is u8, so we need to limit the size of the SDP URI. Enforce
this both in the NLA policy and in the code that performs the allocation
and copy, to avoid writing past the end of the allocated buffer.

Fixes: d9b8d8e19b073 ("NFC: llcp: Service Name Lookup netlink interface")
Signed-off-by: Kees Cook 
---
No reply from linux-wireless, so sending to netdev directly now...
---
 net/nfc/llcp_commands.c | 4 
 net/nfc/netlink.c   | 3 ++-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/net/nfc/llcp_commands.c b/net/nfc/llcp_commands.c
index 367d8c027101..2ceefa183cee 100644
--- a/net/nfc/llcp_commands.c
+++ b/net/nfc/llcp_commands.c
@@ -149,6 +149,10 @@ struct nfc_llcp_sdp_tlv *nfc_llcp_build_sdreq_tlv(u8 tid, 
char *uri,
 
pr_debug("uri: %s, len: %zu\n", uri, uri_len);
 
+   /* sdreq->tlv_len is u8, takes uri_len, + 3 for header, + 1 for NULL */
+   if (WARN_ON_ONCE(uri_len > U8_MAX - 4))
+   return NULL;
+
sdreq = kzalloc(sizeof(struct nfc_llcp_sdp_tlv), GFP_KERNEL);
if (sdreq == NULL)
return NULL;
diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c
index c0b83dc9d993..f018eafc2a0d 100644
--- a/net/nfc/netlink.c
+++ b/net/nfc/netlink.c
@@ -61,7 +61,8 @@ static const struct nla_policy nfc_genl_policy[NFC_ATTR_MAX + 
1] = {
 };
 
 static const struct nla_policy nfc_sdp_genl_policy[NFC_SDP_ATTR_MAX + 1] = {
-   [NFC_SDP_ATTR_URI] = { .type = NLA_STRING },
+   [NFC_SDP_ATTR_URI] = { .type = NLA_STRING,
+  .len = U8_MAX - 4 },
[NFC_SDP_ATTR_SAP] = { .type = NLA_U8 },
 };
 
-- 
2.7.4


-- 
Kees Cook
Pixel Security


Re: [PATCH 0/3] Remove IPVlan module dependencies on IPv6 and Netfilter

2018-02-14 Thread Florian Westphal
Matteo Croce  wrote:
> The IPVlan module currently depends on IPv6 and Netfilter.
> Refactor the code to allow building IPVlan module regardless of the value of
> CONFIG_IPV6 and CONFIG_NETFILTER.
> Also change the dependency to CONFIG_NET_L3_MASTER_DEV into a select,
> as compiling L3 Master device alone has no sense.

4fbae7d83c98c30efc implies that both netfilter and l3mdev are needed
for l3s mode, yet I see no option of that in changelog or a change that
rejects this mode.

Am I missing anything?



Re: [PATCH RFC net-next 0/7] net/ipv6: Add support for path selection using hash of 5-tuple

2018-02-14 Thread David Ahern
On 2/14/18 3:45 PM, Or Gerlitz wrote:
> On Tue, Feb 13, 2018 at 5:21 PM, David Ahern  wrote:
>> On 2/13/18 5:42 AM, Ido Schimmel wrote:
>>> On Tue, Feb 13, 2018 at 01:03:14PM +0200, Or Gerlitz wrote:
 On Tue, Feb 13, 2018 at 2:05 AM, David Ahern  wrote:
> Hardware supports multipath selection using the standard L4 5-tuple
> instead of just L3 and the flow label. In addition, some network
> operators prefer IPv6 path selection to use the 5-tuple.

 The HW supports using flow label and AFAIK that is the preferred approach
 by the community (?)

> To that end, add support to IPv6 for multipath hash policy

 so a question comes up if/what are the disadvantaged
 to support 5-tuple. E.g Tom was commenting that such DPI is problematic
 when multiple IPv6 header extensions are used.
>>
>> Pros and cons to both approaches (L3 only or L4). We (Cumulus Networks)
>> use L4 5-tuple hash for both IPv4 and IPv6. When I asked around various
>> experts all of them gave me a puzzled look as to why I was asking the
>> question. Basically, the unanimous response was of course it is an L4 hash.
> 
> how the various systems you are dealing with do with traffic that involves
> ipv6 extension headers? what about environments with GRE? in ipv4 GRE
> fabrics are just broken for ECMP, in ipv6 they can fly with flow label but
> will crash again with L4 hash.
> 

If you like your ecmp hash algorithm, you can keep your ecmp hash algorithm.

This gives users a choice; it is not a requirement to move from L3 only
to L4. Further, this makes IPv6 on par with IPv4 with a choice between
L3 and L4 and allows users to decide what works best for them.


Re: [PATCH net-next 7/7] tools: tc-testing: Update README and TODO

2018-02-14 Thread Lucas Bates
On Wed, Feb 14, 2018 at 2:09 PM, Brenda J. Butler  wrote:
> Signed-off-by: Brenda J. Butler 

Acked-by: Lucas Bates 
> ---
>  tools/testing/selftests/tc-testing/README   | 173 
> +---
>  tools/testing/selftests/tc-testing/TODO.txt |  25 +++-
>  2 files changed, 179 insertions(+), 19 deletions(-)
>
> diff --git a/tools/testing/selftests/tc-testing/README 
> b/tools/testing/selftests/tc-testing/README
> index 970ff294fec8..3a0336782d2d 100644
> --- a/tools/testing/selftests/tc-testing/README
> +++ b/tools/testing/selftests/tc-testing/README
> @@ -14,11 +14,11 @@ REQUIREMENTS
>
>  *  The kernel must have network namespace support
>
> -*   The kernel must have veth support available, as a veth pair is created
> +*  The kernel must have veth support available, as a veth pair is created
> prior to running the tests.
>
> -*  All tc-related features must be built in or available as modules.
> -   To check what is required in current setup run:
> +*  All tc-related features being tested must be built in or available as
> +   modules.  To check what is required in current setup run:
> ./tdc.py -c
>
> Note:
> @@ -44,10 +44,13 @@ using the -p option when running tdc:
>  RUNNING TDC
>  ---
>
> -To use tdc, root privileges are required. tdc will not run otherwise.
> +To use tdc, root privileges are required.  This is because the
> +commands being tested must be run as root.  The code that enforces
> +execution by root uid has been moved into a plugin (see PLUGIN
> +ARCHITECTURE, below).
>
> -All tests are executed inside a network namespace to prevent conflicts
> -within the host.
> +If nsPlugin is linked, all tests are executed inside a network
> +namespace to prevent conflicts within the host.
>
>  Running tdc without any arguments will run all tests. Refer to the section
>  on command line arguments for more information, or run:
> @@ -59,6 +62,33 @@ output captured from the failing test will be printed 
> immediately following
>  the failed test in the TAP output.
>
>
> +OVERVIEW OF TDC EXECUTION
> +-
> +
> +One run of tests is considered a "test suite" (this will be refined in the
> +future).  A test suite has one or more test cases in it.
> +
> +A test case has four stages:
> +
> +  - setup
> +  - execute
> +  - verify
> +  - teardown
> +
> +The setup and teardown stages can run zero or more commands.  The setup
> +stage does some setup if the test needs it.  The teardown stage undoes
> +the setup and returns the system to a "neutral" state so any other test
> +can be run next.  These two stages require any commands run to return
> +success, but do not otherwise verify the results.
> +
> +The execute and verify stages each run one command.  The execute stage
> +tests the return code against one or more acceptable values.  The
> +verify stage checks the return code for success, and also compares
> +the stdout with a regular expression.
> +
> +Each of the commands in any stage will run in a shell instance.
> +
> +
>  USER-DEFINED CONSTANTS
>  --
>
> @@ -70,23 +100,132 @@ executed as part of the test. More will be added as 
> test cases require.
>  Example:
> $TC qdisc add dev $DEV1 ingress
>
> +The NAMES values are used to substitute into the commands in the test cases.
> +
>
>  COMMAND LINE ARGUMENTS
>  --
>
>  Run tdc.py -h to see the full list of available arguments.
>
> --p PATH   Specify the tc executable located at PATH to be used on 
> this
> -  test run
> --cShow the available test case categories in this test file
> --c CATEGORY   Run only tests that belong to CATEGORY
> --f FILE   Read test cases from the JSON file named FILE
> --l [CATEGORY] List all test cases in the JSON file. If CATEGORY is
> -  specified, list test cases matching that category.
> --s ID Show the test case matching ID
> --e ID Execute the test case identified by ID
> --iGenerate unique ID numbers for test cases with no existing
> -  ID number
> +usage: tdc.py [-h] [-p PATH] [-D DIR [DIR ...]] [-f FILE [FILE ...]]
> +  [-c [CATG [CATG ...]]] [-e ID [ID ...]] [-l] [-s] [-i] [-v]
> +  [-d DEVICE] [-n NS] [-V]
> +
> +Linux TC unit tests
> +
> +optional arguments:
> +  -h, --helpshow this help message and exit
> +  -p PATH, --path PATH  The full path to the tc executable to use
> +  -v, --verbose Show the commands that are being run
> +  -d DEVICE, --device DEVICE
> +Execute the test case in flower category
> +
> +selection:
> +  select which test cases: files plus directories; filtered by categories
> +  plus testids
> +
> +  -D DIR [DIR ...], --directory DIR [DIR ...]
> +Collect tests from the specified directory(ies)
> +

Re: Serious performance degradation in Linux 4.15

2018-02-14 Thread Matt Fleming
On Mon, 12 Feb, at 04:16:42PM, Peter Zijlstra wrote:
> On Fri, Feb 09, 2018 at 05:59:12PM +, Jon Maloy wrote:
> > Command for TCP:
> > "netperf TCP_STREAM  (netperf -n 4 -f m -c 4 -C 4 -P 1 -H 10.0.0.1 -t 
> > TCP_STREAM -l 10 -- -O THROUGHPUT)"
> > Command for TIPC:
> > "netperf TIPC_STREAM (netperf -n 4 -f m -c 4 -C 4 -P 1 -H 10.0.0.1 -t 
> > TCP_STREAM -l 10 -- -O THROUGHPUT)"
> 
> That looks like identical tests to me. And my netperf (debian testing)
> doesn't appear to have -t TIPC_STREAM.
> 
> Please try a coherent report and I'll have another look. Don't (again)
> forget to mention what kind of setup you're running this on.
> 
> 
> On my IVB-EP (2 sockets, 10 cores, 2 threads), performance cpufreq,
> PTI=n RETPOLINE=n, I get:

Here's some more numbers. This is with RETPOLINE=y but you'll see it
doesn't make much of a difference. Oh, this is also with powersave
cpufreq governor.

The 'tip+' column is tip/master, commit ca96ad6978c3 ("Merge branch 'x86/mm'")

The 'tip-plus-patch+' column is tip/master plus Peter's patch from
20180212151642.gu25...@hirez.programming.kicks-ass.net


netperf-tcp
4.15.0-rc1 4.15.0 
4.16.0-rc1 4.16.0-rc1
   vanillavanilla   
tip+tip-plus-patch+
Min   641804.73 (   0.00%)  951.28 ( -47.29%)  956.77 ( 
-46.99%)  936.19 ( -48.13%)
Min   128   3352.00 (   0.00%) 1847.80 ( -44.87%) 1831.41 ( 
-45.36%) 1808.88 ( -46.04%)
Min   256   5619.02 (   0.00%) 3327.27 ( -40.79%) 3287.00 ( 
-41.50%) 3311.33 ( -41.07%)
Min   1024 17325.58 (   0.00%)11053.24 ( -36.20%)11098.91 ( 
-35.94%)10892.59 ( -37.13%)
Min   2048 27564.59 (   0.00%)18311.31 ( -33.57%)18649.89 ( 
-32.34%)18327.69 ( -33.51%)
Min   3312 33677.30 (   0.00%)25254.43 ( -25.01%)24897.65 ( 
-26.07%)25464.71 ( -24.39%)
Min   4096 35624.64 (   0.00%)28186.09 ( -20.88%)27317.58 ( 
-23.32%)27046.46 ( -24.08%)
Min   8192 42950.87 (   0.00%)33407.18 ( -22.22%)34133.19 ( 
-20.53%)33429.82 ( -22.17%)
Min   1638446798.74 (   0.00%)40020.99 ( -14.48%)40761.81 ( 
-12.90%)40370.88 ( -13.74%)
Hmean 641818.68 (   0.00%)  959.16 ( -47.26%)  962.40 ( 
-47.08%)  954.96 ( -47.49%)
Hmean 128   3405.06 (   0.00%) 1860.21 ( -45.37%) 1844.12 ( 
-45.84%) 1849.44 ( -45.69%)
Hmean 256   5777.53 (   0.00%) 3371.67 ( -41.64%) 3341.43 ( 
-42.17%) 3360.35 ( -41.84%)
Hmean 1024 17679.46 (   0.00%)11326.96 ( -35.93%)11192.24 ( 
-36.69%)11219.22 ( -36.54%)
Hmean 2048 27764.04 (   0.00%)18864.94 ( -32.05%)18833.51 ( 
-32.17%)18740.31 ( -32.50%)
Hmean 3312 35253.65 (   0.00%)25444.33 ( -27.82%)25700.57 ( 
-27.10%)25610.63 ( -27.35%)
Hmean 4096 36479.20 (   0.00%)28636.63 ( -21.50%)28073.90 ( 
-23.04%)27856.51 ( -23.64%)
Hmean 8192 43386.27 (   0.00%)34771.52 ( -19.86%)35213.44 ( 
-18.84%)34603.90 ( -20.24%)
Hmean 1638447487.74 (   0.00%)41329.50 ( -12.97%)41096.73 ( 
-13.46%)40787.33 ( -14.11%)
Stddev64  12.42 (   0.00%)6.35 (  48.87%)5.77 (  
53.54%)   12.21 (   1.73%)
Stddev128 45.84 (   0.00%)9.25 (  79.82%)   13.49 (  
70.57%)   23.86 (  47.95%)
Stddev256 90.59 (   0.00%)   30.55 (  66.28%)   37.07 (  
59.08%)   28.66 (  68.36%)
Stddev1024   322.33 (   0.00%)  164.75 (  48.89%)  119.05 (  
63.07%)  265.42 (  17.65%)
Stddev2048   153.04 (   0.00%)  424.98 (-177.70%)  176.40 ( 
-15.26%)  242.90 ( -58.72%)
Stddev3312  1024.93 (   0.00%)  182.58 (  82.19%)  585.07 (  
42.92%)  108.93 (  89.37%)
Stddev4096   696.34 (   0.00%)  433.20 (  37.79%)  626.42 (  
10.04%)  712.05 (  -2.26%)
Stddev8192   478.31 (   0.00%)  808.23 ( -68.98%)  794.39 ( 
-66.08%)  698.27 ( -45.99%)
Stddev16384  720.05 (   0.00%)  816.70 ( -13.42%)  412.26 (  
42.75%)  325.43 (  54.81%)
CoeffVar  64   0.68 (   0.00%)0.66 (   3.05%)0.60 (  
12.20%)1.28 ( -87.13%)
CoeffVar  128  1.35 (   0.00%)0.50 (  63.06%)0.73 (  
45.66%)1.29 (   4.17%)
CoeffVar  256  1.57 (   0.00%)0.91 (  42.21%)1.11 (  
29.24%)0.85 (  45.59%)
CoeffVar  1024 1.82 (   0.00%)1.45 (  20.22%)1.06 (  
41.65%)2.36 ( -29.74%)
CoeffVar  2048 0.55 (   0.00%)2.25 (-308.53%)0.94 ( 
-69.91%)1.30 (-135.12%)
CoeffVar  3312 2.91 (   0.00%)0.72 (  75.30%)2.28 (  
21.68%)0.43 (  85.36%)
CoeffVar  4096 1.91 (   0.00%)1.51 (  20.74%)

Re: [PATCH net-next 6/7] tools: tc-testing: valgrindPlugin

2018-02-14 Thread Lucas Bates
On Wed, Feb 14, 2018 at 2:09 PM, Brenda J. Butler  wrote:
> Run the command under test under valgrind.  Produce an extra set of
> tap output for the memory check on each test.
>
> Signed-off-by: Brenda J. Butler 

Acked-by: Lucas Bates 

> ---
>  .../tc-testing/plugin-lib/valgrindPlugin.py| 142 
> +
>  1 file changed, 142 insertions(+)
>  create mode 100644 
> tools/testing/selftests/tc-testing/plugin-lib/valgrindPlugin.py
>
> diff --git a/tools/testing/selftests/tc-testing/plugin-lib/valgrindPlugin.py 
> b/tools/testing/selftests/tc-testing/plugin-lib/valgrindPlugin.py
> new file mode 100644
> index ..477a7bd7d7fb
> --- /dev/null
> +++ b/tools/testing/selftests/tc-testing/plugin-lib/valgrindPlugin.py
> @@ -0,0 +1,142 @@
> +'''
> +run the command under test, under valgrind and collect memory leak info
> +as a separate test.
> +'''
> +
> +
> +import os
> +import re
> +import signal
> +from string import Template
> +import subprocess
> +import time
> +from TdcPlugin import TdcPlugin
> +
> +from tdc_config import *
> +
> +def vp_extract_num_from_string(num_as_string_maybe_with_commas):
> +return int(num_as_string_maybe_with_commas.replace(',',''))
> +
> +class SubPlugin(TdcPlugin):
> +def __init__(self):
> +self.sub_class = 'valgrind/SubPlugin'
> +self.tap = ''
> +super().__init__()
> +
> +def pre_suite(self, testcount, testidlist):
> +'''run commands before test_runner goes into a test loop'''
> +super().pre_suite(testcount, testidlist)
> +if self.args.verbose > 1:
> +print('{}.pre_suite'.format(self.sub_class))
> +if self.args.valgrind:
> +self._add_to_tap('1..{}\n'.format(self.testcount))
> +
> +def post_suite(self, index):
> +'''run commands after test_runner goes into a test loop'''
> +super().post_suite(index)
> +self._add_to_tap('\n|---\n')
> +if self.args.verbose > 1:
> +print('{}.post_suite'.format(self.sub_class))
> +print('{}'.format(self.tap))
> +if self.args.verbose < 4:
> +subprocess.check_output('rm -f vgnd-*.log', shell=True)
> +
> +def add_args(self, parser):
> +super().add_args(parser)
> +self.argparser_group = self.argparser.add_argument_group(
> +'valgrind',
> +'options for valgrindPlugin (run command under test under 
> Valgrind)')
> +
> +self.argparser_group.add_argument(
> +'-V', '--valgrind', action='store_true',
> +help='Run commands under valgrind')
> +
> +return self.argparser
> +
> +def adjust_command(self, stage, command):
> +super().adjust_command(stage, command)
> +cmdform = 'list'
> +cmdlist = list()
> +
> +if not self.args.valgrind:
> +return command
> +
> +if self.args.verbose > 1:
> +print('{}.adjust_command'.format(self.sub_class))
> +
> +if not isinstance(command, list):
> +cmdform = 'str'
> +cmdlist = command.split()
> +else:
> +cmdlist = command
> +
> +if stage == 'execute':
> +if self.args.verbose > 1:
> +print('adjust_command:  stage is {}; inserting valgrind 
> stuff in command [{}] list [{}]'.
> +  format(stage, command, cmdlist))
> +cmdlist.insert(0, '--track-origins=yes')
> +cmdlist.insert(0, '--show-leak-kinds=definite,indirect')
> +cmdlist.insert(0, '--leak-check=full')
> +cmdlist.insert(0, 
> '--log-file=vgnd-{}.log'.format(self.args.testid))
> +cmdlist.insert(0, '-v')  # ask for summary of non-leak errors
> +cmdlist.insert(0, ENVIR['VALGRIND_BIN'])
> +else:
> +pass
> +
> +if cmdform == 'str':
> +command = ' '.join(cmdlist)
> +else:
> +command = cmdlist
> +
> +if self.args.verbose > 1:
> +print('adjust_command:  return command [{}]'.format(command))
> +return command
> +
> +def post_execute(self):
> +if not self.args.valgrind:
> +return
> +
> +self.definitely_lost_re = re.compile(
> +r'definitely lost:\s+([,0-9]+)\s+bytes in\s+([,0-9]+)\sblocks', 
> re.MULTILINE | re.DOTALL)
> +self.indirectly_lost_re = re.compile(
> +r'indirectly lost:\s+([,0-9]+)\s+bytes in\s+([,0-9]+)\s+blocks', 
> re.MULTILINE | re.DOTALL)
> +self.possibly_lost_re = re.compile(
> +r'possibly lost:\s+([,0-9]+)bytes in\s+([,0-9]+)\s+blocks', 
> re.MULTILINE | re.DOTALL)
> +self.non_leak_error_re = re.compile(
> +r'ERROR SUMMARY:\s+([,0-9]+) errors 
> from\s+([,0-9]+)\s+contexts', re.MULTILINE | re.DOTALL)
> +
> +def_num = 0
> +ind_num = 0
> +pos_num = 0
> +nle_num = 0
> +
> +# 

Re: [PATCH net-next 5/7] tools: tc-testing: nsPlugin

2018-02-14 Thread Lucas Bates
On Wed, Feb 14, 2018 at 2:09 PM, Brenda J. Butler  wrote:
> Move the functionality of creating a namespace before the test suite
> and destroying it afterwards to a plugin.
>
> Signed-off-by: Brenda J. Butler 
Acked-by: Lucas Bates 


> ---
>  .../selftests/tc-testing/plugin-lib/nsPlugin.py| 141 
> +
>  tools/testing/selftests/tc-testing/tdc.py  |  45 +--
>  2 files changed, 142 insertions(+), 44 deletions(-)
>  create mode 100644 tools/testing/selftests/tc-testing/plugin-lib/nsPlugin.py
>
> diff --git a/tools/testing/selftests/tc-testing/plugin-lib/nsPlugin.py 
> b/tools/testing/selftests/tc-testing/plugin-lib/nsPlugin.py
> new file mode 100644
> index ..a194b1af2b30
> --- /dev/null
> +++ b/tools/testing/selftests/tc-testing/plugin-lib/nsPlugin.py
> @@ -0,0 +1,141 @@
> +import os
> +import signal
> +from string import Template
> +import subprocess
> +import time
> +from TdcPlugin import TdcPlugin
> +
> +from tdc_config import *
> +
> +class SubPlugin(TdcPlugin):
> +def __init__(self):
> +self.sub_class = 'ns/SubPlugin'
> +super().__init__()
> +
> +def pre_suite(self, testcount, testidlist):
> +'''run commands before test_runner goes into a test loop'''
> +super().pre_suite(testcount, testidlist)
> +
> +if self.args.namespace:
> +self._ns_create()
> +
> +def post_suite(self, index):
> +'''run commands after test_runner goes into a test loop'''
> +super().post_suite(index)
> +if self.args.verbose:
> +print('{}.post_suite'.format(self.sub_class))
> +
> +if self.args.namespace:
> +self._ns_destroy()
> +
> +def add_args(self, parser):
> +super().add_args(parser)
> +self.argparser_group = self.argparser.add_argument_group(
> +'netns',
> +'options for nsPlugin(run commands in net namespace)')
> +self.argparser_group.add_argument(
> +'-n', '--namespace', action='store_true',
> +help='Run commands in namespace')
> +return self.argparser
> +
> +def adjust_command(self, stage, command):
> +super().adjust_command(stage, command)
> +cmdform = 'list'
> +cmdlist = list()
> +
> +if not self.args.namespace:
> +return command
> +
> +if self.args.verbose:
> +print('{}.adjust_command'.format(self.sub_class))
> +
> +if not isinstance(command, list):
> +cmdform = 'str'
> +cmdlist = command.split()
> +else:
> +cmdlist = command
> +if stage == 'setup' or stage == 'execute' or stage == 'verify' or 
> stage == 'teardown':
> +if self.args.verbose:
> +print('adjust_command:  stage is {}; inserting netns stuff 
> in command [{}] list [{}]'.format(stage, command, cmdlist))
> +cmdlist.insert(0, self.args.NAMES['NS'])
> +cmdlist.insert(0, 'exec')
> +cmdlist.insert(0, 'netns')
> +cmdlist.insert(0, 'ip')
> +else:
> +pass
> +
> +if cmdform == 'str':
> +command = ' '.join(cmdlist)
> +else:
> +command = cmdlist
> +
> +if self.args.verbose:
> +print('adjust_command:  return command [{}]'.format(command))
> +return command
> +
> +def _ns_create(self):
> +'''
> +Create the network namespace in which the tests will be run and set 
> up
> +the required network devices for it.
> +'''
> +if self.args.namespace:
> +cmd = 'ip netns add {}'.format(self.args.NAMES['NS'])
> +self._exec_cmd('pre', cmd)
> +cmd = 'ip link add $DEV0 type veth peer name $DEV1'
> +self._exec_cmd('pre', cmd)
> +cmd = 'ip link set $DEV1 netns {}'.format(self.args.NAMES['NS'])
> +self._exec_cmd('pre', cmd)
> +cmd = 'ip link set $DEV0 up'
> +self._exec_cmd('pre', cmd)
> +cmd = 'ip -n {} link set $DEV1 up'.format(self.args.NAMES['NS'])
> +self._exec_cmd('pre', cmd)
> +if self.args.device:
> +cmd = 'ip link set $DEV2 netns 
> {}'.format(self.args.NAMES['NS'])
> +self._exec_cmd('pre', cmd)
> +cmd = 'ip -n {} link set $DEV2 
> up'.format(self.args.NAMES['NS'])
> +self._exec_cmd('pre', cmd)
> +
> +def _ns_destroy(self):
> +'''
> +Destroy the network namespace for testing (and any associated network
> +devices as well)
> +'''
> +if self.args.namespace:
> +cmd = 'ip netns delete {}'.format(self.args.NAMES['NS'])
> +self._exec_cmd('post', cmd)
> +
> +def _exec_cmd(self, stage, command):
> +'''
> +Perform any required modifications on an executable command, then run
> +  

Re: [PATCH RFC net-next 0/7] net/ipv6: Add support for path selection using hash of 5-tuple

2018-02-14 Thread Or Gerlitz
On Tue, Feb 13, 2018 at 3:16 PM, Or Gerlitz  wrote:

> [...] note we have two ends to deal with here (1) generation (2) usage
>
> E.g if the kernel generates flow label but uses source port we have 
> inconsistent
> environment. Problem is that the generation and usage typically don't happen
> on the same network point.

David, what's your thinking here? e.g for overly networks environments


Re: [PATCH net-next 3/7] tools: tc-testing: Introduce plugin architecture

2018-02-14 Thread Lucas Bates
On Wed, Feb 14, 2018 at 2:09 PM, Brenda J. Butler  wrote:
> This should be a general test architecture, and yet allow specific
> tests to be done.  Introduce a plugin architecture.
>
> An individual test has 4 stages, setup/execute/verify/teardown.  Each
> plugin gets a chance to run a function at each stage, plus one call
> before all the tests are called ("pre" suite) and one after all the
> tests are called ("post" suite).  In addition, just before each
> command is executed, the plugin gets a chance to modify the command
> using the "adjust_command" hook.  This makes the test suite quite
> flexible.
>
> Future patches will take some functionality out of the tdc.py script and
> place it in plugins.
>
> To use the plugins, place the implementation in the plugins directory
> and run tdc.py.  It will notice the plugins and use them.
>
> Signed-off-by: Brenda J. Butler 

Acked-by: Lucas Bates 
> ---
>  tools/testing/selftests/tc-testing/TdcPlugin.py|  74 +++
>  .../tc-testing/creating-plugins/AddingPlugins.txt  | 104 ++
>  .../selftests/tc-testing/plugin-lib/README-PLUGINS |  27 +++
>  .../selftests/tc-testing/plugins/__init__.py   |   0
>  tools/testing/selftests/tc-testing/tdc.py  | 221 
> +++--
>  5 files changed, 368 insertions(+), 58 deletions(-)
>  create mode 100644 tools/testing/selftests/tc-testing/TdcPlugin.py
>  create mode 100644 
> tools/testing/selftests/tc-testing/creating-plugins/AddingPlugins.txt
>  create mode 100644 
> tools/testing/selftests/tc-testing/plugin-lib/README-PLUGINS
>  create mode 100644 tools/testing/selftests/tc-testing/plugins/__init__.py
>
> diff --git a/tools/testing/selftests/tc-testing/TdcPlugin.py 
> b/tools/testing/selftests/tc-testing/TdcPlugin.py
> new file mode 100644
> index ..3ee9a6dacb52
> --- /dev/null
> +++ b/tools/testing/selftests/tc-testing/TdcPlugin.py
> @@ -0,0 +1,74 @@
> +#!/usr/bin/env python3
> +
> +class TdcPlugin:
> +def __init__(self):
> +super().__init__()
> +print(' -- {}.__init__'.format(self.sub_class))
> +
> +def pre_suite(self, testcount, testidlist):
> +'''run commands before test_runner goes into a test loop'''
> +self.testcount = testcount
> +self.testidlist = testidlist
> +if self.args.verbose > 1:
> +print(' -- {}.pre_suite'.format(self.sub_class))
> +
> +def post_suite(self, index):
> +'''run commands after test_runner completes the test loop
> +index is the last ordinal number of test that was attempted'''
> +if self.args.verbose > 1:
> +print(' -- {}.post_suite'.format(self.sub_class))
> +
> +def pre_case(self, test_ordinal, testid):
> +'''run commands before test_runner does one test'''
> +if self.args.verbose > 1:
> +print(' -- {}.pre_case'.format(self.sub_class))
> +self.args.testid = testid
> +self.args.test_ordinal = test_ordinal
> +
> +def post_case(self):
> +'''run commands after test_runner does one test'''
> +if self.args.verbose > 1:
> +print(' -- {}.post_case'.format(self.sub_class))
> +
> +def pre_execute(self):
> +'''run command before test-runner does the execute step'''
> +if self.args.verbose > 1:
> +print(' -- {}.pre_execute'.format(self.sub_class))
> +
> +def post_execute(self):
> +'''run command after test-runner does the execute step'''
> +if self.args.verbose > 1:
> +print(' -- {}.post_execute'.format(self.sub_class))
> +
> +def adjust_command(self, stage, command):
> +'''adjust the command'''
> +if self.args.verbose > 1:
> +print(' -- {}.adjust_command {}'.format(self.sub_class, stage))
> +
> +# if stage == 'pre':
> +# pass
> +# elif stage == 'setup':
> +# pass
> +# elif stage == 'execute':
> +# pass
> +# elif stage == 'verify':
> +# pass
> +# elif stage == 'teardown':
> +# pass
> +# elif stage == 'post':
> +# pass
> +# else:
> +# pass
> +
> +return command
> +
> +def add_args(self, parser):
> +'''Get the plugin args from the command line'''
> +self.argparser = parser
> +return self.argparser
> +
> +def check_args(self, args, remaining):
> +'''Check that the args are set correctly'''
> +self.args = args
> +if self.args.verbose > 1:
> +print(' -- {}.check_args'.format(self.sub_class))
> diff --git 
> a/tools/testing/selftests/tc-testing/creating-plugins/AddingPlugins.txt 
> b/tools/testing/selftests/tc-testing/creating-plugins/AddingPlugins.txt
> new file mode 100644
> index ..c18f88d09360
> --- /dev/null
> +++ b/tools/testing/selftests/tc-testing/creating-plugins/AddingPlugins.txt
> @@ -0,0 +1,104 

Re: [PATCH RFC net-next 0/7] net/ipv6: Add support for path selection using hash of 5-tuple

2018-02-14 Thread Or Gerlitz
On Tue, Feb 13, 2018 at 5:21 PM, David Ahern  wrote:
> On 2/13/18 5:42 AM, Ido Schimmel wrote:
>> On Tue, Feb 13, 2018 at 01:03:14PM +0200, Or Gerlitz wrote:
>>> On Tue, Feb 13, 2018 at 2:05 AM, David Ahern  wrote:
 Hardware supports multipath selection using the standard L4 5-tuple
 instead of just L3 and the flow label. In addition, some network
 operators prefer IPv6 path selection to use the 5-tuple.
>>>
>>> The HW supports using flow label and AFAIK that is the preferred approach
>>> by the community (?)
>>>
 To that end, add support to IPv6 for multipath hash policy
>>>
>>> so a question comes up if/what are the disadvantaged
>>> to support 5-tuple. E.g Tom was commenting that such DPI is problematic
>>> when multiple IPv6 header extensions are used.
>
> Pros and cons to both approaches (L3 only or L4). We (Cumulus Networks)
> use L4 5-tuple hash for both IPv4 and IPv6. When I asked around various
> experts all of them gave me a puzzled look as to why I was asking the
> question. Basically, the unanimous response was of course it is an L4 hash.

how the various systems you are dealing with do with traffic that involves
ipv6 extension headers? what about environments with GRE? in ipv4 GRE
fabrics are just broken for ECMP, in ipv6 they can fly with flow label but
will crash again with L4 hash.


Re: [PATCH net-next 4/7] tools: tc-testing: rootPlugin

2018-02-14 Thread Lucas Bates
On Wed, Feb 14, 2018 at 2:09 PM, Brenda J. Butler  wrote:
> Move the functionality that checks for root permissions into a plugin.
>
> Signed-off-by: Brenda J. Butler 
Acked-by: Lucas Bates 
> ---
>  .../selftests/tc-testing/plugin-lib/rootPlugin.py | 19 
> +++
>  tools/testing/selftests/tc-testing/tdc.py |  4 
>  2 files changed, 19 insertions(+), 4 deletions(-)
>  create mode 100644 
> tools/testing/selftests/tc-testing/plugin-lib/rootPlugin.py
>
> diff --git a/tools/testing/selftests/tc-testing/plugin-lib/rootPlugin.py 
> b/tools/testing/selftests/tc-testing/plugin-lib/rootPlugin.py
> new file mode 100644
> index ..e36775bd4d12
> --- /dev/null
> +++ b/tools/testing/selftests/tc-testing/plugin-lib/rootPlugin.py
> @@ -0,0 +1,19 @@
> +import os
> +import sys
> +from TdcPlugin import TdcPlugin
> +
> +from tdc_config import *
> +
> +
> +class SubPlugin(TdcPlugin):
> +def __init__(self):
> +self.sub_class = 'root/SubPlugin'
> +super().__init__()
> +
> +def pre_suite(self, testcount, testidlist):
> +# run commands before test_runner goes into a test loop
> +super().pre_suite(testcount, testidlist)
> +
> +if os.geteuid():
> +print('This script must be run with root privileges', 
> file=sys.stderr)
> +exit(1)
> diff --git a/tools/testing/selftests/tc-testing/tdc.py 
> b/tools/testing/selftests/tc-testing/tdc.py
> index 3e6f9f2e1691..a718d2b57739 100755
> --- a/tools/testing/selftests/tc-testing/tdc.py
> +++ b/tools/testing/selftests/tc-testing/tdc.py
> @@ -579,10 +579,6 @@ def set_operation_mode(pm, args):
>  list_test_cases(alltests)
>  exit(0)
>
> -if (os.geteuid() != 0):
> -print("This script must be run with root privileges.\n")
> -exit(1)
> -
>  ns_create(args, pm)
>
>  if len(alltests):
> --
> 2.15.1
>


Re: [PATCH net-next 2/7] tools: tc-testing: Refactor test-runner

2018-02-14 Thread Lucas Bates
On Wed, Feb 14, 2018 at 2:09 PM, Brenda J. Butler  wrote:
> Split the test_runner function into the loop part (test_runner)
> and the contents (run_one_test) for maintainability.
> It makes it a little easier to catch exceptions
> in an individual test, and keep going (and flush a bunch
> of tap results for the skipped tests).
>
> Signed-off-by: Brenda J. Butler 

Acked-by: Lucas Bates 

> ---
>  tools/testing/selftests/tc-testing/tdc.py | 81 
> ---
>  1 file changed, 52 insertions(+), 29 deletions(-)
>
> diff --git a/tools/testing/selftests/tc-testing/tdc.py 
> b/tools/testing/selftests/tc-testing/tdc.py
> index ef3a8881e458..a2624eda34db 100755
> --- a/tools/testing/selftests/tc-testing/tdc.py
> +++ b/tools/testing/selftests/tc-testing/tdc.py
> @@ -85,9 +85,42 @@ def prepare_env(cmdlist):
>  print("\nError message:")
>  print(foutput)
>  print("\nAborting test run.")
> -ns_destroy()
> -exit(1)
> +# ns_destroy()
> +raise Exception('prepare_env did not complete successfully')
> +
> +def run_one_test(index, tidx):
> +result = True
> +tresult = ""
> +tap = ""
> +print("Test " + tidx["id"] + ": " + tidx["name"])
> +prepare_env(tidx["setup"])
> +(p, procout) = exec_cmd(tidx["cmdUnderTest"])
> +exit_code = p.returncode
> +
> +if (exit_code != int(tidx["expExitCode"])):
> +result = False
> +print("exit:", exit_code, int(tidx["expExitCode"]))
> +print(procout)
> +else:
> +match_pattern = re.compile(str(tidx["matchPattern"]),
> +   re.DOTALL | re.MULTILINE)
> +(p, procout) = exec_cmd(tidx["verifyCmd"])
> +match_index = re.findall(match_pattern, procout)
> +if len(match_index) != int(tidx["matchCount"]):
> +result = False
> +
> +if not result:
> +tresult += "not "
> +tresult += "ok {} - {} # {}\n".format(str(index), tidx['id'], 
> tidx["name"])
> +tap += tresult
>
> +if result == False:
> +tap += procout
> +
> +prepare_env(tidx["teardown"])
> +index += 1
> +
> +return tap
>
>  def test_runner(filtered_tests, args):
>  """
> @@ -104,37 +137,27 @@ def test_runner(filtered_tests, args):
>  tap = str(index) + ".." + str(tcount) + "\n"
>
>  for tidx in testlist:
> -result = True
> -tresult = ""
>  if "flower" in tidx["category"] and args.device == None:
>  continue
> -print("Test " + tidx["id"] + ": " + tidx["name"])
> -prepare_env(tidx["setup"])
> -(p, procout) = exec_cmd(tidx["cmdUnderTest"])
> -exit_code = p.returncode
> -
> -if (exit_code != int(tidx["expExitCode"])):
> -result = False
> -print("exit:", exit_code, int(tidx["expExitCode"]))
> -print(procout)
> -else:
> -match_pattern = re.compile(str(tidx["matchPattern"]), re.DOTALL)
> -(p, procout) = exec_cmd(tidx["verifyCmd"])
> -match_index = re.findall(match_pattern, procout)
> -if len(match_index) != int(tidx["matchCount"]):
> -result = False
> -
> -if result == True:
> -tresult += "ok "
> -else:
> -tresult += "not ok "
> -tap += tresult + str(index) + " " + tidx["id"] + " " + tidx["name"] 
> + "\n"
> +try:
> +badtest = tidx  # in case it goes bad
> +tap += run_one_test(index, tidx)
> +except Exception as ee:
> +print('Exception {} (caught in test_runner, running test {} {} 
> {})'.
> +  format(ee, index, tidx['id'], tidx['name']))
> +break
> +index += 1
>
> -if result == False:
> -tap += procout
> +count = index
> +tap += 'about to flush the tap output if tests need to be skipped\n'
> +if tcount + 1 != index:
> +for tidx in testlist[index - 1:]:
> +msg = 'skipped - previous setup or teardown failed'
> +tap += 'ok {} - {} # {} {} {} \n'.format(
> +count, tidx['id'], msg, index, badtest.get('id', 
> '--Unknown--'))
> +count += 1
>
> -prepare_env(tidx["teardown"])
> -index += 1
> +tap += 'done flushing skipped test tap output\n'
>
>  return tap
>
> --
> 2.15.1
>


Re: [PATCH net-next 1/7] tools: tc-testing: Command line parms

2018-02-14 Thread Lucas Bates
On Wed, Feb 14, 2018 at 2:09 PM, Brenda J. Butler  wrote:
> Separate the functionality of the command line parameters into "selection"
> parameters, "action" parameters and other parameters.
>
> "Selection" parameters are for choosing which tests on which to act.
> "Action" parameters are for choosing what to do with the selected tests.
> "Other" parameters are for global effect (like "help" or "verbose").
>
> With this commit, we add the ability to name a directory as another
> selection mechanism.  We can accumulate a number of tests by directory,
> file, category, or even by test id, instead of being constrained to
> run all tests in one collection or just one test.
>
> Signed-off-by: Brenda J. Butler 

Acked-by: Lucas Bates 

> ---
>  .../creating-testcases/AddingTestCases.txt |  35 +++-
>  tools/testing/selftests/tc-testing/tdc.py  | 209 
> +
>  tools/testing/selftests/tc-testing/tdc_helper.py   |  15 +-
>  3 files changed, 164 insertions(+), 95 deletions(-)
>
> diff --git 
> a/tools/testing/selftests/tc-testing/creating-testcases/AddingTestCases.txt 
> b/tools/testing/selftests/tc-testing/creating-testcases/AddingTestCases.txt
> index 00438331ba47..17b267dedbd9 100644
> --- 
> a/tools/testing/selftests/tc-testing/creating-testcases/AddingTestCases.txt
> +++ 
> b/tools/testing/selftests/tc-testing/creating-testcases/AddingTestCases.txt
> @@ -12,14 +12,18 @@ template.json for the required JSON format for test cases.
>  Include the 'id' field, but do not assign a value. Running tdc with the -i
>  option will generate a unique ID for that test case.
>
> -tdc will recursively search the 'tc' subdirectory for .json files.  Any
> -test case files you create in these directories will automatically be 
> included.
> -If you wish to store your custom test cases elsewhere, be sure to run tdc
> -with the -f argument and the path to your file.
> +tdc will recursively search the 'tc-tests' subdirectory (or the
> +directories named with the -D option) for .json files.  Any test case
> +files you create in these directories will automatically be included.
> +If you wish to store your custom test cases elsewhere, be sure to run
> +tdc with the -f argument and the path to your file, or the -D argument
> +and the path to your directory(ies).
>
> -Be aware of required escape characters in the JSON data - particularly when
> -defining the match pattern. Refer to the tctests.json file for examples when
> -in doubt.
> +Be aware of required escape characters in the JSON data - particularly
> +when defining the match pattern. Refer to the supplied json test files
> +for examples when in doubt.  The match pattern is written in json, and
> +will be used by python.  So the match pattern will be a python regular
> +expression, but should be written using json syntax.
>
>
>  TEST CASE STRUCTURE
> @@ -69,7 +73,8 @@ SETUP/TEARDOWN ERRORS
>  If an error is detected during the setup/teardown process, execution of the
>  tests will immediately stop with an error message and the namespace in which
>  the tests are run will be destroyed. This is to prevent inaccurate results
> -in the test cases.
> +in the test cases.  tdc will output a series of TAP results for the skipped
> +tests.
>
>  Repeated failures of the setup/teardown may indicate a problem with the test
>  case, or possibly even a bug in one of the commands that are not being 
> tested.
> @@ -79,3 +84,17 @@ so that it doesn't halt the script for an error that 
> doesn't matter. Turn the
>  individual command into a list, with the command being first, followed by all
>  acceptable exit codes for the command.
>
> +Example:
> +
> +A pair of setup commands.  The first can have exit code 0, 1 or 255, the
> +second must have exit code 0.
> +
> +"setup": [
> +[
> +"$TC actions flush action gact",
> +0,
> +1,
> +255
> +],
> +"$TC actions add action reclassify index 65536"
> +],
> diff --git a/tools/testing/selftests/tc-testing/tdc.py 
> b/tools/testing/selftests/tc-testing/tdc.py
> index fc373fdf2bdc..ef3a8881e458 100755
> --- a/tools/testing/selftests/tc-testing/tdc.py
> +++ b/tools/testing/selftests/tc-testing/tdc.py
> @@ -209,20 +209,41 @@ def set_args(parser):
>  """
>  Set the command line arguments for tdc.
>  """
> -parser.add_argument('-p', '--path', type=str,
> -help='The full path to the tc executable to use')
> -parser.add_argument('-c', '--category', type=str, nargs='?', const='+c',
> -help='Run tests only from the specified category, or 
> if no category is specified, list known categories.')
> -parser.add_argument('-f', '--file', type=str,
> -help='Run tests from the specified file')
> -parser.add_argument('-l', '--list', type=str, nargs='?', const="++", 
> 

Re: [PATCH net-next] kcm: Call strp_stop before strp_done in kcm_attach

2018-02-14 Thread Eric Dumazet
On Wed, 2018-02-14 at 15:38 -0500, David Miller wrote:
> From: Tom Herbert 
> Date: Wed, 14 Feb 2018 09:22:42 -0800
> 
> > In kcm_attach strp_done is called when sk_user_data is already
> > set to fail the attach. strp_done needs the strp to be stopped and
> > warns if it isn't. Call strp_stop in this case to eliminate the
> > warning message.
> > 
> > Reported-by: syzbot+88dfb55e4c8b770d8...@syzkaller.appspotmail.com
> > Fixes: e5571240236c5652f ("kcm: Check if sk_user_data already set in 
> > kcm_attach"
> > Signed-off-by: Tom Herbert 
> 
> Applied, thanks Tom.


If bug was add added in e5571240236c5652f then this patch should have
targeted net tree.




Re: [PATCH V2 net-next 4/7] rds: support for zcopy completion notification

2018-02-14 Thread Willem de Bruijn
On Wed, Feb 14, 2018 at 1:50 PM, Santosh Shilimkar
 wrote:
> On 2/14/2018 2:28 AM, Sowmini Varadhan wrote:
>>
>> RDS removes a datagram (rds_message) from the retransmit queue when
>> an ACK is received. The ACK indicates that the receiver has queued
>> the RDS datagram, so that the sender can safely forget the datagram.
>> When all references to the rds_message are quiesced, rds_message_purge
>> is called to release resources used by the rds_message
>>
>> If the datagram to be removed had pinned pages set up, add
>> an entry to the rs->rs_znotify_queue so that the notifcation
>> will be sent up via rds_rm_zerocopy_callback() when the
>> rds_message is eventually freed by rds_message_purge.
>>
>> rds_rm_zerocopy_callback() attempts to batch the number of cookies
>> sent with each notification  to a max of SO_EE_ORIGIN_MAX_ZCOOKIES.
>> This is achieved by checking the tail skb in the sk_error_queue:
>> if this has room for one more cookie, the cookie from the
>> current notification is added; else a new skb is added to the
>> sk_error_queue. Every invocation of rds_rm_zerocopy_callback() will
>> trigger a ->sk_error_report to notify the application.
>>
>> Signed-off-by: Sowmini Varadhan 
>> ---
>> v2:
>>- make sure to always sock_put m_rs even if there is no znotifier.
>>- major rewrite of notification, resulting in much simplification.
>>
>>   include/uapi/linux/errqueue.h |2 +
>>   net/rds/af_rds.c  |2 +
>>   net/rds/message.c |   83
>> +---
>>   net/rds/rds.h |   14 +++
>>   net/rds/recv.c|2 +
>>   5 files changed, 96 insertions(+), 7 deletions(-)
>>
> generic comment and please update it where it is applicable
> in terms of variable names, notifiers etc.
>
> RDS support true zero copy already with RDMA transport so some of
> this code can easily get confused.
>
> So I suggest something like below.
> s/zerocopy/zeromsgcopy
> s/zcopy/zmsgcopy
> s/zcookie/zmsgcpycookie
> s/znotifier/zmsgcpynotifier
>
>
>> diff --git a/include/uapi/linux/errqueue.h b/include/uapi/linux/errqueue.h
>> index dc64cfa..28812ed 100644
>> --- a/include/uapi/linux/errqueue.h
>> +++ b/include/uapi/linux/errqueue.h
>> @@ -20,11 +20,13 @@ struct sock_extended_err {
>>   #define SO_EE_ORIGIN_ICMP63
>>   #define SO_EE_ORIGIN_TXSTATUS 4
>>   #define SO_EE_ORIGIN_ZEROCOPY 5
>> +#define SO_EE_ORIGIN_ZCOOKIE   6
>>   #define SO_EE_ORIGIN_TIMESTAMPING SO_EE_ORIGIN_TXSTATUS
>> #define SO_EE_OFFENDER(ee)  ((struct sockaddr*)((ee)+1))
>> #define SO_EE_CODE_ZEROCOPY_COPIED  1
>> +#defineSO_EE_ORIGIN_MAX_ZCOOKIES   8
>
>
> This error change might need to go though other subsystem tree. May
> be you can seperate it and also copy "linux-...@vger.kernel.org"

Previous changes to this file also went in through net-next, so this is
fine. The error queue is a socket, so network, datastructure.

As for naming, zerocopy is unfortunately an overused term. I did not
help matters when adding msg_zerocopy. That said, let's try to keep
consistent naming across socket families, so no zmsg prefix only in
RDS.


[PATCH net-next] net/ipv4: Remove fib table id from rtable

2018-02-14 Thread David Ahern
Remove rt_table_id from rtable. It was added for getroute to return the
table id that was hit in the lookup. With the changes for fibmatch the
table id can be extracted from the fib_info returned in the fib_result
so it no longer needs to be in rtable directly.

Signed-off-by: David Ahern 
---
 drivers/net/vrf.c   | 1 -
 include/net/route.h | 2 --
 net/ipv4/route.c| 9 +
 net/ipv4/xfrm4_policy.c | 1 -
 4 files changed, 1 insertion(+), 12 deletions(-)

diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c
index 139c61c8244a..239c78c53e58 100644
--- a/drivers/net/vrf.c
+++ b/drivers/net/vrf.c
@@ -736,7 +736,6 @@ static int vrf_rtable_create(struct net_device *dev)
return -ENOMEM;
 
rth->dst.output = vrf_output;
-   rth->rt_table_id = vrf->tb_id;
 
rcu_assign_pointer(vrf->rth, rth);
 
diff --git a/include/net/route.h b/include/net/route.h
index 1eb9ce470e25..158833ea7988 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -65,8 +65,6 @@ struct rtable {
/* Miscellaneous cached information */
u32 rt_pmtu;
 
-   u32 rt_table_id;
-
struct list_headrt_uncached;
struct uncached_list*rt_uncached_list;
 };
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 6ce623e3e2ab..5ca7415cd48c 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1509,7 +1509,6 @@ struct rtable *rt_dst_alloc(struct net_device *dev,
rt->rt_pmtu = 0;
rt->rt_gateway = 0;
rt->rt_uses_gateway = 0;
-   rt->rt_table_id = 0;
INIT_LIST_HEAD(>rt_uncached);
 
rt->dst.output = ip_output;
@@ -1727,8 +1726,6 @@ static int __mkroute_input(struct sk_buff *skb,
}
 
rth->rt_is_input = 1;
-   if (res->table)
-   rth->rt_table_id = res->table->tb_id;
RT_CACHE_STAT_INC(in_slow_tot);
 
rth->dst.input = ip_forward;
@@ -2001,8 +1998,6 @@ out:  return err;
rth->dst.tclassid = itag;
 #endif
rth->rt_is_input = 1;
-   if (res->table)
-   rth->rt_table_id = res->table->tb_id;
 
RT_CACHE_STAT_INC(in_slow_tot);
if (res->type == RTN_UNREACHABLE) {
@@ -2231,8 +2226,6 @@ static struct rtable *__mkroute_output(const struct 
fib_result *res,
return ERR_PTR(-ENOBUFS);
 
rth->rt_iif = orig_oif;
-   if (res->table)
-   rth->rt_table_id = res->table->tb_id;
 
RT_CACHE_STAT_INC(out_slow_tot);
 
@@ -2762,7 +2755,7 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, 
struct nlmsghdr *nlh,
rt->rt_flags |= RTCF_NOTIFY;
 
if (rtm->rtm_flags & RTM_F_LOOKUP_TABLE)
-   table_id = rt->rt_table_id;
+   table_id = res.table ? res.table->tb_id : 0;
 
if (rtm->rtm_flags & RTM_F_FIB_MATCH) {
if (!res.fi) {
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index 753f526cf9db..796ac4115485 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -100,7 +100,6 @@ static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct 
net_device *dev,
xdst->u.rt.rt_gateway = rt->rt_gateway;
xdst->u.rt.rt_uses_gateway = rt->rt_uses_gateway;
xdst->u.rt.rt_pmtu = rt->rt_pmtu;
-   xdst->u.rt.rt_table_id = rt->rt_table_id;
INIT_LIST_HEAD(>u.rt.rt_uncached);
 
return 0;
-- 
2.11.0



Re: [PATCH net v4 02/13] net/8390: Fix msg_enable patch snafu

2018-02-14 Thread David Miller
From: Finn Thain 
Date: Thu, 15 Feb 2018 09:11:13 +1100 (AEDT)

> On Tue, 13 Feb 2018, David Miller wrote:
> 
>> > I think you have overlooked those modules which offer no way to set 
>> > p->msg_enable, i.e. ax88796, axnet_cs, etherh, hydra, mac8390, 
>> > mcf8390, pcnet_cs and zorro8390.
>> 
>> Then that's a bug, we have a very simple easy to implement interface for 
>> setting this (ethtool).
>> 
>> And by adding the simple hook, you will make these older drivers easier 
>> to debug for the few people still using them.
> 
> Have you considered that implementing the ethtool hooks in the core driver 
> might allow removal of all 8390 driver 'msg_enable' module parameters and 
> msglevel ethtool hooks added by c45f812f0280, excepting those in the core 
> driver? But even if we did that, it seems to me that we still need this 
> patch.

No, because the module parameter lets you set the default msg level at
the time the driver loads, so you can control messages printed very
early on before it is practical to invoke ethtool and set the msg
level.

This is why most drivers have this module parameter, and implement
such a scheme.


[PATCHv2 net-next 1/8] net: sched: act: fix code style

2018-02-14 Thread Alexander Aring
This patch is used by subsequent patches. It fixes code style issues
caught by checkpatch.

Signed-off-by: Alexander Aring 
---
 include/net/act_api.h  |  5 +++--
 net/sched/act_api.c| 12 ++--
 net/sched/act_mirred.c |  6 +++---
 3 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/include/net/act_api.h b/include/net/act_api.h
index 6ed9692f20bd..32ef544f4ddc 100644
--- a/include/net/act_api.h
+++ b/include/net/act_api.h
@@ -87,12 +87,13 @@ struct tc_action_ops {
   struct tcf_result *);
int (*dump)(struct sk_buff *, struct tc_action *, int, int);
void(*cleanup)(struct tc_action *);
-   int (*lookup)(struct net *, struct tc_action **, u32);
+   int (*lookup)(struct net *net, struct tc_action **a, u32 index);
int (*init)(struct net *net, struct nlattr *nla,
struct nlattr *est, struct tc_action **act, int ovr,
int bind);
int (*walk)(struct net *, struct sk_buff *,
-   struct netlink_callback *, int, const struct 
tc_action_ops *);
+   struct netlink_callback *, int,
+   const struct tc_action_ops *);
void(*stats_update)(struct tc_action *, u64, u32, u64);
struct net_device *(*get_dev)(const struct tc_action *a);
 };
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 4886ea4a7d6e..becc63689fae 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -621,7 +621,7 @@ struct tc_action *tcf_action_init_1(struct net *net, struct 
tcf_proto *tp,
goto err_out;
err = -EINVAL;
kind = tb[TCA_ACT_KIND];
-   if (kind == NULL)
+   if (!kind)
goto err_out;
if (nla_strlcpy(act_name, kind, IFNAMSIZ) >= IFNAMSIZ)
goto err_out;
@@ -822,7 +822,7 @@ static int tca_get_fill(struct sk_buff *skb, struct 
list_head *actions,
t->tca__pad2 = 0;
 
nest = nla_nest_start(skb, TCA_ACT_TAB);
-   if (nest == NULL)
+   if (!nest)
goto out_nlmsg_trim;
 
if (tcf_action_dump(skb, actions, bind, ref) < 0)
@@ -934,7 +934,7 @@ static int tca_action_flush(struct net *net, struct nlattr 
*nla,
t->tca__pad2 = 0;
 
nest = nla_nest_start(skb, TCA_ACT_TAB);
-   if (nest == NULL)
+   if (!nest)
goto out_module_put;
 
err = ops->walk(net, skb, , RTM_DELACTION, ops);
@@ -1005,10 +1005,10 @@ tca_action_gd(struct net *net, struct nlattr *nla, 
struct nlmsghdr *n,
return ret;
 
if (event == RTM_DELACTION && n->nlmsg_flags & NLM_F_ROOT) {
-   if (tb[1] != NULL)
+   if (tb[1])
return tca_action_flush(net, tb[1], n, portid);
-   else
-   return -EINVAL;
+
+   return -EINVAL;
}
 
for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c
index e6ff88f72900..abcd5f12b913 100644
--- a/net/sched/act_mirred.c
+++ b/net/sched/act_mirred.c
@@ -80,12 +80,12 @@ static int tcf_mirred_init(struct net *net, struct nlattr 
*nla,
bool exists = false;
int ret;
 
-   if (nla == NULL)
+   if (!nla)
return -EINVAL;
ret = nla_parse_nested(tb, TCA_MIRRED_MAX, nla, mirred_policy, NULL);
if (ret < 0)
return ret;
-   if (tb[TCA_MIRRED_PARMS] == NULL)
+   if (!tb[TCA_MIRRED_PARMS])
return -EINVAL;
parm = nla_data(tb[TCA_MIRRED_PARMS]);
 
@@ -117,7 +117,7 @@ static int tcf_mirred_init(struct net *net, struct nlattr 
*nla,
}
 
if (!exists) {
-   if (dev == NULL)
+   if (!dev)
return -EINVAL;
ret = tcf_idr_create(tn, parm->index, est, a,
 _mirred_ops, bind, true);
-- 
2.11.0



Re: [PATCH V2 net-next 4/7] rds: support for zcopy completion notification

2018-02-14 Thread Santosh Shilimkar

On 2/14/2018 1:25 PM, Sowmini Varadhan wrote:

On (02/14/18 13:10), Santosh Shilimkar wrote:

RDS support true zero copy already with RDMA transport so some of
this code can easily get confused.


btw, another way to solve this is to have the RDMA code use the
suffix "rdma" (which is what it really is) as needed.


And same breath,here zcopy is No message from user ;-)
ZCOPY is otherwise often tied with RDMA directly.

Renaming churns are not that useful and I definitely agree
with what Dave said if it was renaming change to the
existing code like what you are suggesting with 'rdma'

Anyways I don't want to contest this too much since I can
follow that code and know what each does and means :-)

The comment was long term readability perspective for
some one completely new reading the code and being able to
distinguish the different modes.

Regards,
Santosh


[PATCHv2 net-next 2/8] net: sched: act: add extack to init

2018-02-14 Thread Alexander Aring
This patch adds extack to tcf_action_init and tcf_action_init_1
functions. These are necessary to make individual extack handling in
each act implementation.

Based on work by David Ahern 

Cc: David Ahern 
Signed-off-by: Alexander Aring 
---
 include/net/act_api.h |  5 +++--
 net/sched/act_api.c   | 17 +++--
 net/sched/cls_api.c   |  4 ++--
 3 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/include/net/act_api.h b/include/net/act_api.h
index 32ef544f4ddc..41d95930ffbc 100644
--- a/include/net/act_api.h
+++ b/include/net/act_api.h
@@ -163,10 +163,11 @@ int tcf_action_exec(struct sk_buff *skb, struct tc_action 
**actions,
int nr_actions, struct tcf_result *res);
 int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,
struct nlattr *est, char *name, int ovr, int bind,
-   struct list_head *actions);
+   struct list_head *actions, struct netlink_ext_ack *extack);
 struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
struct nlattr *nla, struct nlattr *est,
-   char *name, int ovr, int bind);
+   char *name, int ovr, int bind,
+   struct netlink_ext_ack *extack);
 int tcf_action_dump(struct sk_buff *skb, struct list_head *, int, int);
 int tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int, int);
 int tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int, int);
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index becc63689fae..8d89b026414f 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -605,7 +605,8 @@ static struct tc_cookie *nla_memdup_cookie(struct nlattr 
**tb)
 
 struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
struct nlattr *nla, struct nlattr *est,
-   char *name, int ovr, int bind)
+   char *name, int ovr, int bind,
+   struct netlink_ext_ack *extack)
 {
struct tc_action *a;
struct tc_action_ops *a_o;
@@ -726,7 +727,7 @@ static void cleanup_a(struct list_head *actions, int ovr)
 
 int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,
struct nlattr *est, char *name, int ovr, int bind,
-   struct list_head *actions)
+   struct list_head *actions, struct netlink_ext_ack *extack)
 {
struct nlattr *tb[TCA_ACT_MAX_PRIO + 1];
struct tc_action *act;
@@ -738,7 +739,8 @@ int tcf_action_init(struct net *net, struct tcf_proto *tp, 
struct nlattr *nla,
return err;
 
for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
-   act = tcf_action_init_1(net, tp, tb[i], est, name, ovr, bind);
+   act = tcf_action_init_1(net, tp, tb[i], est, name, ovr, bind,
+   extack);
if (IS_ERR(act)) {
err = PTR_ERR(act);
goto err;
@@ -1060,12 +1062,14 @@ tcf_add_notify(struct net *net, struct nlmsghdr *n, 
struct list_head *actions,
 }
 
 static int tcf_action_add(struct net *net, struct nlattr *nla,
- struct nlmsghdr *n, u32 portid, int ovr)
+ struct nlmsghdr *n, u32 portid, int ovr,
+ struct netlink_ext_ack *extack)
 {
int ret = 0;
LIST_HEAD(actions);
 
-   ret = tcf_action_init(net, NULL, nla, NULL, NULL, ovr, 0, );
+   ret = tcf_action_init(net, NULL, nla, NULL, NULL, ovr, 0, ,
+ extack);
if (ret)
return ret;
 
@@ -1113,7 +1117,8 @@ static int tc_ctl_action(struct sk_buff *skb, struct 
nlmsghdr *n,
if (n->nlmsg_flags & NLM_F_REPLACE)
ovr = 1;
 replay:
-   ret = tcf_action_add(net, tca[TCA_ACT_TAB], n, portid, ovr);
+   ret = tcf_action_add(net, tca[TCA_ACT_TAB], n, portid, ovr,
+extack);
if (ret == -EAGAIN)
goto replay;
break;
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 2bc1bc23d42e..f21610c5da1a 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -1434,7 +1434,7 @@ int tcf_exts_validate(struct net *net, struct tcf_proto 
*tp, struct nlattr **tb,
if (exts->police && tb[exts->police]) {
act = tcf_action_init_1(net, tp, tb[exts->police],
rate_tlv, "police", ovr,
-   TCA_ACT_BIND);
+   TCA_ACT_BIND, extack);
if (IS_ERR(act))
  

[PATCHv2 net-next 0/8] net: sched: act: add extack support

2018-02-14 Thread Alexander Aring
Hi,

this patch series adds extack support for the TC action subsystem.
As example I for the extack support in a TC action I choosed mirred
action.

- Alex

Cc: David Ahern 

changes since v2:

- remove newline in extack of generic walker handling
  Thanks to Davide Caratti
- add ker...@mojatatu.com in cc

Alexander Aring (8):
  net: sched: act: fix code style
  net: sched: act: add extack to init
  net: sched: act: handle generic action errors
  net: sched: act: add extack to init callback
  net: sched: act: add extack for lookup callback
  net: sched: act: add extack for walk callback
  net: sched: act: handle extack in tcf_generic_walker
  net: sched: act: mirred: add extack support

 include/net/act_api.h  |  17 --
 net/sched/act_api.c| 135 +
 net/sched/act_bpf.c|  10 ++--
 net/sched/act_connmark.c   |  11 ++--
 net/sched/act_csum.c   |  10 ++--
 net/sched/act_gact.c   |  10 ++--
 net/sched/act_ife.c|  10 ++--
 net/sched/act_ipt.c|  20 ---
 net/sched/act_mirred.c |  25 ++---
 net/sched/act_nat.c|  11 ++--
 net/sched/act_pedit.c  |  10 ++--
 net/sched/act_police.c |  11 ++--
 net/sched/act_sample.c |  10 ++--
 net/sched/act_simple.c |  10 ++--
 net/sched/act_skbedit.c|  10 ++--
 net/sched/act_skbmod.c |  10 ++--
 net/sched/act_tunnel_key.c |  10 ++--
 net/sched/act_vlan.c   |  10 ++--
 net/sched/cls_api.c|   4 +-
 19 files changed, 215 insertions(+), 129 deletions(-)

-- 
2.11.0



[PATCHv2 net-next 4/8] net: sched: act: add extack to init callback

2018-02-14 Thread Alexander Aring
This patch adds extack support for act init callback api. This
prepares to handle extack support inside each specific act
implementation.

Based on work by David Ahern 

Cc: David Ahern 
Signed-off-by: Alexander Aring 
---
 include/net/act_api.h  | 2 +-
 net/sched/act_api.c| 5 +++--
 net/sched/act_bpf.c| 2 +-
 net/sched/act_connmark.c   | 3 ++-
 net/sched/act_csum.c   | 2 +-
 net/sched/act_gact.c   | 2 +-
 net/sched/act_ife.c| 2 +-
 net/sched/act_ipt.c| 4 ++--
 net/sched/act_mirred.c | 2 +-
 net/sched/act_nat.c| 3 ++-
 net/sched/act_pedit.c  | 2 +-
 net/sched/act_police.c | 3 ++-
 net/sched/act_sample.c | 2 +-
 net/sched/act_simple.c | 2 +-
 net/sched/act_skbedit.c| 2 +-
 net/sched/act_skbmod.c | 2 +-
 net/sched/act_tunnel_key.c | 2 +-
 net/sched/act_vlan.c   | 2 +-
 18 files changed, 24 insertions(+), 20 deletions(-)

diff --git a/include/net/act_api.h b/include/net/act_api.h
index 41d95930ffbc..3717e0f2bb1b 100644
--- a/include/net/act_api.h
+++ b/include/net/act_api.h
@@ -90,7 +90,7 @@ struct tc_action_ops {
int (*lookup)(struct net *net, struct tc_action **a, u32 index);
int (*init)(struct net *net, struct nlattr *nla,
struct nlattr *est, struct tc_action **act, int ovr,
-   int bind);
+   int bind, struct netlink_ext_ack *extack);
int (*walk)(struct net *, struct sk_buff *,
struct netlink_callback *, int,
const struct tc_action_ops *);
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index a5138ae026a1..00c5a1d9a21e 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -680,9 +680,10 @@ struct tc_action *tcf_action_init_1(struct net *net, 
struct tcf_proto *tp,
 
/* backward compatibility for policer */
if (name == NULL)
-   err = a_o->init(net, tb[TCA_ACT_OPTIONS], est, , ovr, bind);
+   err = a_o->init(net, tb[TCA_ACT_OPTIONS], est, , ovr, bind,
+   extack);
else
-   err = a_o->init(net, nla, est, , ovr, bind);
+   err = a_o->init(net, nla, est, , ovr, bind, extack);
if (err < 0)
goto err_mod;
 
diff --git a/net/sched/act_bpf.c b/net/sched/act_bpf.c
index b3f2c15affa7..b3ebfa9598e2 100644
--- a/net/sched/act_bpf.c
+++ b/net/sched/act_bpf.c
@@ -272,7 +272,7 @@ static void tcf_bpf_prog_fill_cfg(const struct tcf_bpf 
*prog,
 
 static int tcf_bpf_init(struct net *net, struct nlattr *nla,
struct nlattr *est, struct tc_action **act,
-   int replace, int bind)
+   int replace, int bind, struct netlink_ext_ack *extack)
 {
struct tc_action_net *tn = net_generic(net, bpf_net_id);
struct nlattr *tb[TCA_ACT_BPF_MAX + 1];
diff --git a/net/sched/act_connmark.c b/net/sched/act_connmark.c
index 2b15ba84e0c8..20e0215360b5 100644
--- a/net/sched/act_connmark.c
+++ b/net/sched/act_connmark.c
@@ -96,7 +96,8 @@ static const struct nla_policy 
connmark_policy[TCA_CONNMARK_MAX + 1] = {
 
 static int tcf_connmark_init(struct net *net, struct nlattr *nla,
 struct nlattr *est, struct tc_action **a,
-int ovr, int bind)
+int ovr, int bind,
+struct netlink_ext_ack *extack)
 {
struct tc_action_net *tn = net_generic(net, connmark_net_id);
struct nlattr *tb[TCA_CONNMARK_MAX + 1];
diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c
index b7ba9b06b147..3b8c48bb2683 100644
--- a/net/sched/act_csum.c
+++ b/net/sched/act_csum.c
@@ -46,7 +46,7 @@ static struct tc_action_ops act_csum_ops;
 
 static int tcf_csum_init(struct net *net, struct nlattr *nla,
 struct nlattr *est, struct tc_action **a, int ovr,
-int bind)
+int bind, struct netlink_ext_ack *extack)
 {
struct tc_action_net *tn = net_generic(net, csum_net_id);
struct tcf_csum_params *params_old, *params_new;
diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c
index b56986d41c87..912f3398f1c1 100644
--- a/net/sched/act_gact.c
+++ b/net/sched/act_gact.c
@@ -56,7 +56,7 @@ static const struct nla_policy gact_policy[TCA_GACT_MAX + 1] 
= {
 
 static int tcf_gact_init(struct net *net, struct nlattr *nla,
 struct nlattr *est, struct tc_action **a,
-int ovr, int bind)
+int ovr, int bind, struct netlink_ext_ack *extack)
 {
struct tc_action_net *tn = net_generic(net, gact_net_id);
struct nlattr *tb[TCA_GACT_MAX + 1];
diff --git a/net/sched/act_ife.c b/net/sched/act_ife.c
index 5954e992685a..e5127d400737 100644
--- a/net/sched/act_ife.c
+++ b/net/sched/act_ife.c
@@ -447,7 +447,7 @@ 

[PATCHv2 net-next 3/8] net: sched: act: handle generic action errors

2018-02-14 Thread Alexander Aring
This patch adds extack support for generic act handling. The extack
will be set deeper to each called function which is not part of netdev
core api.

Based on work by David Ahern 

Cc: David Ahern 
Signed-off-by: Alexander Aring 
---
 net/sched/act_api.c | 93 +++--
 1 file changed, 61 insertions(+), 32 deletions(-)

diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 8d89b026414f..a5138ae026a1 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -617,31 +617,40 @@ struct tc_action *tcf_action_init_1(struct net *net, 
struct tcf_proto *tp,
int err;
 
if (name == NULL) {
-   err = nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL, NULL);
+   err = nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL, extack);
if (err < 0)
goto err_out;
err = -EINVAL;
kind = tb[TCA_ACT_KIND];
-   if (!kind)
+   if (!kind) {
+   NL_SET_ERR_MSG(extack, "TC action kind must be 
specified");
goto err_out;
-   if (nla_strlcpy(act_name, kind, IFNAMSIZ) >= IFNAMSIZ)
+   }
+   if (nla_strlcpy(act_name, kind, IFNAMSIZ) >= IFNAMSIZ) {
+   NL_SET_ERR_MSG(extack, "TC action name too long");
goto err_out;
+   }
if (tb[TCA_ACT_COOKIE]) {
int cklen = nla_len(tb[TCA_ACT_COOKIE]);
 
-   if (cklen > TC_COOKIE_MAX_SIZE)
+   if (cklen > TC_COOKIE_MAX_SIZE) {
+   NL_SET_ERR_MSG(extack, "TC cookie size above 
the maximum");
goto err_out;
+   }
 
cookie = nla_memdup_cookie(tb);
if (!cookie) {
+   NL_SET_ERR_MSG(extack, "No memory to generate 
TC cookie");
err = -ENOMEM;
goto err_out;
}
}
} else {
-   err = -EINVAL;
-   if (strlcpy(act_name, name, IFNAMSIZ) >= IFNAMSIZ)
+   if (strlcpy(act_name, name, IFNAMSIZ) >= IFNAMSIZ) {
+   NL_SET_ERR_MSG(extack, "TC action name too long");
+   err = -EINVAL;
goto err_out;
+   }
}
 
a_o = tc_lookup_action_n(act_name);
@@ -664,6 +673,7 @@ struct tc_action *tcf_action_init_1(struct net *net, struct 
tcf_proto *tp,
goto err_mod;
}
 #endif
+   NL_SET_ERR_MSG(extack, "Failed to load TC action module");
err = -ENOENT;
goto err_out;
}
@@ -698,6 +708,7 @@ struct tc_action *tcf_action_init_1(struct net *net, struct 
tcf_proto *tp,
 
list_add_tail(>list, );
tcf_action_destroy(, bind);
+   NL_SET_ERR_MSG(extack, "Failed to init action chain");
return ERR_PTR(err);
}
}
@@ -734,7 +745,7 @@ int tcf_action_init(struct net *net, struct tcf_proto *tp, 
struct nlattr *nla,
int err;
int i;
 
-   err = nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL, NULL);
+   err = nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL, extack);
if (err < 0)
return err;
 
@@ -842,7 +853,8 @@ static int tca_get_fill(struct sk_buff *skb, struct 
list_head *actions,
 
 static int
 tcf_get_notify(struct net *net, u32 portid, struct nlmsghdr *n,
-  struct list_head *actions, int event)
+  struct list_head *actions, int event,
+  struct netlink_ext_ack *extack)
 {
struct sk_buff *skb;
 
@@ -851,6 +863,7 @@ tcf_get_notify(struct net *net, u32 portid, struct nlmsghdr 
*n,
return -ENOBUFS;
if (tca_get_fill(skb, actions, portid, n->nlmsg_seq, 0, event,
 0, 0) <= 0) {
+   NL_SET_ERR_MSG(extack, "Failed to fill netlink tc action 
attributes");
kfree_skb(skb);
return -EINVAL;
}
@@ -859,7 +872,8 @@ tcf_get_notify(struct net *net, u32 portid, struct nlmsghdr 
*n,
 }
 
 static struct tc_action *tcf_action_get_1(struct net *net, struct nlattr *nla,
- struct nlmsghdr *n, u32 portid)
+ struct nlmsghdr *n, u32 portid,
+ struct netlink_ext_ack *extack)
 {
struct nlattr *tb[TCA_ACT_MAX + 1];
const struct tc_action_ops *ops;
@@ -867,20 +881,24 @@ static struct tc_action *tcf_action_get_1(struct net 
*net, struct nlattr *nla,
int index;
int err;
 
-   err = nla_parse_nested(tb, 

[PATCHv2 net-next 8/8] net: sched: act: mirred: add extack support

2018-02-14 Thread Alexander Aring
This patch adds extack support for TC mirred action.

Cc: David Ahern 
Signed-off-by: Alexander Aring 
---
 net/sched/act_mirred.c | 15 +++
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c
index 05c2ebe92eca..fd34015331ab 100644
--- a/net/sched/act_mirred.c
+++ b/net/sched/act_mirred.c
@@ -80,13 +80,17 @@ static int tcf_mirred_init(struct net *net, struct nlattr 
*nla,
bool exists = false;
int ret;
 
-   if (!nla)
+   if (!nla) {
+   NL_SET_ERR_MSG_MOD(extack, "Mirred requires attributes to be 
passed");
return -EINVAL;
-   ret = nla_parse_nested(tb, TCA_MIRRED_MAX, nla, mirred_policy, NULL);
+   }
+   ret = nla_parse_nested(tb, TCA_MIRRED_MAX, nla, mirred_policy, extack);
if (ret < 0)
return ret;
-   if (!tb[TCA_MIRRED_PARMS])
+   if (!tb[TCA_MIRRED_PARMS]) {
+   NL_SET_ERR_MSG_MOD(extack, "Missing required mirred 
parameters");
return -EINVAL;
+   }
parm = nla_data(tb[TCA_MIRRED_PARMS]);
 
exists = tcf_idr_check(tn, parm->index, a, bind);
@@ -102,6 +106,7 @@ static int tcf_mirred_init(struct net *net, struct nlattr 
*nla,
default:
if (exists)
tcf_idr_release(*a, bind);
+   NL_SET_ERR_MSG_MOD(extack, "Unknown mirred option");
return -EINVAL;
}
if (parm->ifindex) {
@@ -117,8 +122,10 @@ static int tcf_mirred_init(struct net *net, struct nlattr 
*nla,
}
 
if (!exists) {
-   if (!dev)
+   if (!dev) {
+   NL_SET_ERR_MSG_MOD(extack, "Specified device does not 
exist");
return -EINVAL;
+   }
ret = tcf_idr_create(tn, parm->index, est, a,
 _mirred_ops, bind, true);
if (ret)
-- 
2.11.0



[PATCHv2 net-next 6/8] net: sched: act: add extack for walk callback

2018-02-14 Thread Alexander Aring
This patch adds extack support for act walker callback api. This
prepares to handle extack support inside each specific act
implementation.

Cc: David Ahern 
Signed-off-by: Alexander Aring 
---
 include/net/act_api.h  | 3 ++-
 net/sched/act_api.c| 4 ++--
 net/sched/act_bpf.c| 3 ++-
 net/sched/act_connmark.c   | 3 ++-
 net/sched/act_csum.c   | 3 ++-
 net/sched/act_gact.c   | 3 ++-
 net/sched/act_ife.c| 3 ++-
 net/sched/act_ipt.c| 6 --
 net/sched/act_mirred.c | 3 ++-
 net/sched/act_nat.c| 3 ++-
 net/sched/act_pedit.c  | 3 ++-
 net/sched/act_police.c | 3 ++-
 net/sched/act_sample.c | 3 ++-
 net/sched/act_simple.c | 3 ++-
 net/sched/act_skbedit.c| 3 ++-
 net/sched/act_skbmod.c | 3 ++-
 net/sched/act_tunnel_key.c | 3 ++-
 net/sched/act_vlan.c   | 3 ++-
 18 files changed, 38 insertions(+), 20 deletions(-)

diff --git a/include/net/act_api.h b/include/net/act_api.h
index 0bd65db506ba..ab3529255377 100644
--- a/include/net/act_api.h
+++ b/include/net/act_api.h
@@ -94,7 +94,8 @@ struct tc_action_ops {
int bind, struct netlink_ext_ack *extack);
int (*walk)(struct net *, struct sk_buff *,
struct netlink_callback *, int,
-   const struct tc_action_ops *);
+   const struct tc_action_ops *,
+   struct netlink_ext_ack *);
void(*stats_update)(struct tc_action *, u64, u32, u64);
struct net_device *(*get_dev)(const struct tc_action *a);
 };
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 6d2a035f1177..cb284a0437eb 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -963,7 +963,7 @@ static int tca_action_flush(struct net *net, struct nlattr 
*nla,
goto out_module_put;
}
 
-   err = ops->walk(net, skb, , RTM_DELACTION, ops);
+   err = ops->walk(net, skb, , RTM_DELACTION, ops, extack);
if (err <= 0)
goto out_module_put;
 
@@ -1253,7 +1253,7 @@ static int tc_dump_action(struct sk_buff *skb, struct 
netlink_callback *cb)
if (nest == NULL)
goto out_module_put;
 
-   ret = a_o->walk(net, skb, cb, RTM_GETACTION, a_o);
+   ret = a_o->walk(net, skb, cb, RTM_GETACTION, a_o, NULL);
if (ret < 0)
goto out_module_put;
 
diff --git a/net/sched/act_bpf.c b/net/sched/act_bpf.c
index d9654b863347..7e01e2c710c4 100644
--- a/net/sched/act_bpf.c
+++ b/net/sched/act_bpf.c
@@ -367,7 +367,8 @@ static void tcf_bpf_cleanup(struct tc_action *act)
 
 static int tcf_bpf_walker(struct net *net, struct sk_buff *skb,
  struct netlink_callback *cb, int type,
- const struct tc_action_ops *ops)
+ const struct tc_action_ops *ops,
+ struct netlink_ext_ack *extack)
 {
struct tc_action_net *tn = net_generic(net, bpf_net_id);
 
diff --git a/net/sched/act_connmark.c b/net/sched/act_connmark.c
index 0504b7600fb6..cb722da0bb15 100644
--- a/net/sched/act_connmark.c
+++ b/net/sched/act_connmark.c
@@ -177,7 +177,8 @@ static inline int tcf_connmark_dump(struct sk_buff *skb, 
struct tc_action *a,
 
 static int tcf_connmark_walker(struct net *net, struct sk_buff *skb,
   struct netlink_callback *cb, int type,
-  const struct tc_action_ops *ops)
+  const struct tc_action_ops *ops,
+  struct netlink_ext_ack *extack)
 {
struct tc_action_net *tn = net_generic(net, connmark_net_id);
 
diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c
index bdd17b9ef034..3e8efadb750f 100644
--- a/net/sched/act_csum.c
+++ b/net/sched/act_csum.c
@@ -631,7 +631,8 @@ static void tcf_csum_cleanup(struct tc_action *a)
 
 static int tcf_csum_walker(struct net *net, struct sk_buff *skb,
   struct netlink_callback *cb, int type,
-  const struct tc_action_ops *ops)
+  const struct tc_action_ops *ops,
+  struct netlink_ext_ack *extack)
 {
struct tc_action_net *tn = net_generic(net, csum_net_id);
 
diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c
index e1e69e38f4b0..d96ebe4bb65a 100644
--- a/net/sched/act_gact.c
+++ b/net/sched/act_gact.c
@@ -201,7 +201,8 @@ static int tcf_gact_dump(struct sk_buff *skb, struct 
tc_action *a,
 
 static int tcf_gact_walker(struct net *net, struct sk_buff *skb,
   struct netlink_callback *cb, int type,
-  const struct tc_action_ops *ops)
+  const struct tc_action_ops *ops,
+  struct netlink_ext_ack *extack)
 {
struct tc_action_net *tn = net_generic(net, gact_net_id);
 
diff --git a/net/sched/act_ife.c b/net/sched/act_ife.c
index 

[PATCHv2 net-next 7/8] net: sched: act: handle extack in tcf_generic_walker

2018-02-14 Thread Alexander Aring
This patch adds extack handling for a common used TC act function
"tcf_generic_walker()" to add an extack message on failures.
The tcf_generic_walker() function can fail if get a invalid command
different than DEL and GET. The naming "action" here is wrong, the
correct naming would be command.

Cc: David Ahern 
Signed-off-by: Alexander Aring 
---
 include/net/act_api.h  | 3 ++-
 net/sched/act_api.c| 6 --
 net/sched/act_bpf.c| 2 +-
 net/sched/act_connmark.c   | 2 +-
 net/sched/act_csum.c   | 2 +-
 net/sched/act_gact.c   | 2 +-
 net/sched/act_ife.c| 2 +-
 net/sched/act_ipt.c| 4 ++--
 net/sched/act_mirred.c | 2 +-
 net/sched/act_nat.c| 2 +-
 net/sched/act_pedit.c  | 2 +-
 net/sched/act_police.c | 2 +-
 net/sched/act_sample.c | 2 +-
 net/sched/act_simple.c | 2 +-
 net/sched/act_skbedit.c| 2 +-
 net/sched/act_skbmod.c | 2 +-
 net/sched/act_tunnel_key.c | 2 +-
 net/sched/act_vlan.c   | 2 +-
 18 files changed, 23 insertions(+), 20 deletions(-)

diff --git a/include/net/act_api.h b/include/net/act_api.h
index ab3529255377..9c2f22695025 100644
--- a/include/net/act_api.h
+++ b/include/net/act_api.h
@@ -140,7 +140,8 @@ static inline void tc_action_net_exit(struct list_head 
*net_list,
 
 int tcf_generic_walker(struct tc_action_net *tn, struct sk_buff *skb,
   struct netlink_callback *cb, int type,
-  const struct tc_action_ops *ops);
+  const struct tc_action_ops *ops,
+  struct netlink_ext_ack *extack);
 int tcf_idr_search(struct tc_action_net *tn, struct tc_action **a, u32 index);
 bool tcf_idr_check(struct tc_action_net *tn, u32 index, struct tc_action **a,
int bind);
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index cb284a0437eb..08f326560d5e 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -202,7 +202,8 @@ static int tcf_del_walker(struct tcf_idrinfo *idrinfo, 
struct sk_buff *skb,
 
 int tcf_generic_walker(struct tc_action_net *tn, struct sk_buff *skb,
   struct netlink_callback *cb, int type,
-  const struct tc_action_ops *ops)
+  const struct tc_action_ops *ops,
+  struct netlink_ext_ack *extack)
 {
struct tcf_idrinfo *idrinfo = tn->idrinfo;
 
@@ -211,7 +212,8 @@ int tcf_generic_walker(struct tc_action_net *tn, struct 
sk_buff *skb,
} else if (type == RTM_GETACTION) {
return tcf_dump_walker(idrinfo, skb, cb);
} else {
-   WARN(1, "tcf_generic_walker: unknown action %d\n", type);
+   WARN(1, "tcf_generic_walker: unknown command %d\n", type);
+   NL_SET_ERR_MSG(extack, "tcf_generic_walker: unknown command");
return -EINVAL;
}
 }
diff --git a/net/sched/act_bpf.c b/net/sched/act_bpf.c
index 7e01e2c710c4..cb3c5d403c88 100644
--- a/net/sched/act_bpf.c
+++ b/net/sched/act_bpf.c
@@ -372,7 +372,7 @@ static int tcf_bpf_walker(struct net *net, struct sk_buff 
*skb,
 {
struct tc_action_net *tn = net_generic(net, bpf_net_id);
 
-   return tcf_generic_walker(tn, skb, cb, type, ops);
+   return tcf_generic_walker(tn, skb, cb, type, ops, extack);
 }
 
 static int tcf_bpf_search(struct net *net, struct tc_action **a, u32 index,
diff --git a/net/sched/act_connmark.c b/net/sched/act_connmark.c
index cb722da0bb15..e4b880fa51fe 100644
--- a/net/sched/act_connmark.c
+++ b/net/sched/act_connmark.c
@@ -182,7 +182,7 @@ static int tcf_connmark_walker(struct net *net, struct 
sk_buff *skb,
 {
struct tc_action_net *tn = net_generic(net, connmark_net_id);
 
-   return tcf_generic_walker(tn, skb, cb, type, ops);
+   return tcf_generic_walker(tn, skb, cb, type, ops, extack);
 }
 
 static int tcf_connmark_search(struct net *net, struct tc_action **a, u32 
index,
diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c
index 3e8efadb750f..d5c2e528d150 100644
--- a/net/sched/act_csum.c
+++ b/net/sched/act_csum.c
@@ -636,7 +636,7 @@ static int tcf_csum_walker(struct net *net, struct sk_buff 
*skb,
 {
struct tc_action_net *tn = net_generic(net, csum_net_id);
 
-   return tcf_generic_walker(tn, skb, cb, type, ops);
+   return tcf_generic_walker(tn, skb, cb, type, ops, extack);
 }
 
 static int tcf_csum_search(struct net *net, struct tc_action **a, u32 index,
diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c
index d96ebe4bb65a..f072bcf33760 100644
--- a/net/sched/act_gact.c
+++ b/net/sched/act_gact.c
@@ -206,7 +206,7 @@ static int tcf_gact_walker(struct net *net, struct sk_buff 
*skb,
 {
struct tc_action_net *tn = net_generic(net, gact_net_id);
 
-   return tcf_generic_walker(tn, skb, cb, type, ops);
+   return tcf_generic_walker(tn, skb, cb, type, ops, extack);
 }
 
 static int tcf_gact_search(struct net *net, struct tc_action **a, u32 index,
diff 

[PATCHv2 net-next 5/8] net: sched: act: add extack for lookup callback

2018-02-14 Thread Alexander Aring
This patch adds extack support for act lookup callback api. This
prepares to handle extack support inside each specific act
implementation.

Cc: David Ahern 
Signed-off-by: Alexander Aring 
---
 include/net/act_api.h  | 3 ++-
 net/sched/act_api.c| 2 +-
 net/sched/act_bpf.c| 3 ++-
 net/sched/act_connmark.c   | 3 ++-
 net/sched/act_csum.c   | 3 ++-
 net/sched/act_gact.c   | 3 ++-
 net/sched/act_ife.c| 3 ++-
 net/sched/act_ipt.c| 6 --
 net/sched/act_mirred.c | 3 ++-
 net/sched/act_nat.c| 3 ++-
 net/sched/act_pedit.c  | 3 ++-
 net/sched/act_police.c | 3 ++-
 net/sched/act_sample.c | 3 ++-
 net/sched/act_simple.c | 3 ++-
 net/sched/act_skbedit.c| 3 ++-
 net/sched/act_skbmod.c | 3 ++-
 net/sched/act_tunnel_key.c | 3 ++-
 net/sched/act_vlan.c   | 3 ++-
 18 files changed, 37 insertions(+), 19 deletions(-)

diff --git a/include/net/act_api.h b/include/net/act_api.h
index 3717e0f2bb1b..0bd65db506ba 100644
--- a/include/net/act_api.h
+++ b/include/net/act_api.h
@@ -87,7 +87,8 @@ struct tc_action_ops {
   struct tcf_result *);
int (*dump)(struct sk_buff *, struct tc_action *, int, int);
void(*cleanup)(struct tc_action *);
-   int (*lookup)(struct net *net, struct tc_action **a, u32 index);
+   int (*lookup)(struct net *net, struct tc_action **a, u32 index,
+ struct netlink_ext_ack *extack);
int (*init)(struct net *net, struct nlattr *nla,
struct nlattr *est, struct tc_action **act, int ovr,
int bind, struct netlink_ext_ack *extack);
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 00c5a1d9a21e..6d2a035f1177 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -901,7 +901,7 @@ static struct tc_action *tcf_action_get_1(struct net *net, 
struct nlattr *nla,
goto err_out;
}
err = -ENOENT;
-   if (ops->lookup(net, , index) == 0)
+   if (ops->lookup(net, , index, extack) == 0)
goto err_mod;
 
module_put(ops->owner);
diff --git a/net/sched/act_bpf.c b/net/sched/act_bpf.c
index b3ebfa9598e2..d9654b863347 100644
--- a/net/sched/act_bpf.c
+++ b/net/sched/act_bpf.c
@@ -374,7 +374,8 @@ static int tcf_bpf_walker(struct net *net, struct sk_buff 
*skb,
return tcf_generic_walker(tn, skb, cb, type, ops);
 }
 
-static int tcf_bpf_search(struct net *net, struct tc_action **a, u32 index)
+static int tcf_bpf_search(struct net *net, struct tc_action **a, u32 index,
+ struct netlink_ext_ack *extack)
 {
struct tc_action_net *tn = net_generic(net, bpf_net_id);
 
diff --git a/net/sched/act_connmark.c b/net/sched/act_connmark.c
index 20e0215360b5..0504b7600fb6 100644
--- a/net/sched/act_connmark.c
+++ b/net/sched/act_connmark.c
@@ -184,7 +184,8 @@ static int tcf_connmark_walker(struct net *net, struct 
sk_buff *skb,
return tcf_generic_walker(tn, skb, cb, type, ops);
 }
 
-static int tcf_connmark_search(struct net *net, struct tc_action **a, u32 
index)
+static int tcf_connmark_search(struct net *net, struct tc_action **a, u32 
index,
+  struct netlink_ext_ack *extack)
 {
struct tc_action_net *tn = net_generic(net, connmark_net_id);
 
diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c
index 3b8c48bb2683..bdd17b9ef034 100644
--- a/net/sched/act_csum.c
+++ b/net/sched/act_csum.c
@@ -638,7 +638,8 @@ static int tcf_csum_walker(struct net *net, struct sk_buff 
*skb,
return tcf_generic_walker(tn, skb, cb, type, ops);
 }
 
-static int tcf_csum_search(struct net *net, struct tc_action **a, u32 index)
+static int tcf_csum_search(struct net *net, struct tc_action **a, u32 index,
+  struct netlink_ext_ack *extack)
 {
struct tc_action_net *tn = net_generic(net, csum_net_id);
 
diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c
index 912f3398f1c1..e1e69e38f4b0 100644
--- a/net/sched/act_gact.c
+++ b/net/sched/act_gact.c
@@ -208,7 +208,8 @@ static int tcf_gact_walker(struct net *net, struct sk_buff 
*skb,
return tcf_generic_walker(tn, skb, cb, type, ops);
 }
 
-static int tcf_gact_search(struct net *net, struct tc_action **a, u32 index)
+static int tcf_gact_search(struct net *net, struct tc_action **a, u32 index,
+  struct netlink_ext_ack *extack)
 {
struct tc_action_net *tn = net_generic(net, gact_net_id);
 
diff --git a/net/sched/act_ife.c b/net/sched/act_ife.c
index e5127d400737..0b70fb0cc609 100644
--- a/net/sched/act_ife.c
+++ b/net/sched/act_ife.c
@@ -831,7 +831,8 @@ static int tcf_ife_walker(struct net *net, struct sk_buff 
*skb,
return tcf_generic_walker(tn, skb, cb, type, ops);
 }
 
-static int tcf_ife_search(struct net *net, struct tc_action **a, u32 index)
+static int tcf_ife_search(struct net *net, struct tc_action 

Re: [PATCH net v4 02/13] net/8390: Fix msg_enable patch snafu

2018-02-14 Thread Finn Thain
On Tue, 13 Feb 2018, David Miller wrote:

> > I think you have overlooked those modules which offer no way to set 
> > p->msg_enable, i.e. ax88796, axnet_cs, etherh, hydra, mac8390, 
> > mcf8390, pcnet_cs and zorro8390.
> 
> Then that's a bug, we have a very simple easy to implement interface for 
> setting this (ethtool).
> 
> And by adding the simple hook, you will make these older drivers easier 
> to debug for the few people still using them.

Have you considered that implementing the ethtool hooks in the core driver 
might allow removal of all 8390 driver 'msg_enable' module parameters and 
msglevel ethtool hooks added by c45f812f0280, excepting those in the core 
driver? But even if we did that, it seems to me that we still need this 
patch.

The missing set_msglevel ethtool hooks and the msg_enable bugs patched 
here are separate issues inasmuchas the lib8390.c module parameter called 
'msg_enable' presently controls only the version message whereas the 
ethtool hooks cannot control the version message logging at all.

I'm not against improving ethtool support. Would you please explain how 
doing so (one way or another) would alter this patch?

-- 


Re: [PATCH iproute2-next v2 2/9] ipaddress: ll_map: Replace ll_idx_n2a() with ll_index_to_name()

2018-02-14 Thread Stephen Hemminger
On Wed, 14 Feb 2018 23:33:37 +0200
Serhey Popovych  wrote:

>   if (tb[IFLA_MASTER]) {
> - SPRINT_BUF(b1);
> + int master = rta_getattr_u32(tb[IFLA_MASTER]);
>  
>   print_string(PRINT_ANY,
>"master",
>"master %s ",
> -  ll_idx_n2a(rta_getattr_u32(tb[IFLA_MASTER]), b1));
> +  ll_index_to_name(master));

Since this is an interface name, it should be printed in the correct color.
Sorry, missed that in the recent changes.


[PATCH bpf-next 2/4] selftests/bpf: Count tests skipped by unpriv

2018-02-14 Thread Joe Stringer
When priviliged tests are skipped due to user rights, count the number of
skipped tests so it's more obvious that the test did not check everything.

Signed-off-by: Joe Stringer 
---
 tools/testing/selftests/bpf/test_verifier.c | 10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/tools/testing/selftests/bpf/test_verifier.c 
b/tools/testing/selftests/bpf/test_verifier.c
index 6cf9bd6f08b7..7ab02526c403 100644
--- a/tools/testing/selftests/bpf/test_verifier.c
+++ b/tools/testing/selftests/bpf/test_verifier.c
@@ -11378,7 +11378,7 @@ static int set_admin(bool admin)
 
 static int do_test(bool unpriv, unsigned int from, unsigned int to)
 {
-   int i, passes = 0, errors = 0;
+   int i, passes = 0, errors = 0, skips = 0;
 
for (i = from; i < to; i++) {
struct bpf_test *test = [i];
@@ -11395,13 +11395,17 @@ static int do_test(bool unpriv, unsigned int from, 
unsigned int to)
set_admin(true);
}
 
-   if (!unpriv) {
+   if (unpriv) {
+   printf("#%d/p %s SKIP\n", i, test->descr);
+   skips++;
+   } else {
printf("#%d/p %s ", i, test->descr);
do_test_single(test, false, , );
}
}
 
-   printf("Summary: %d PASSED, %d FAILED\n", passes, errors);
+   printf("Summary: %d PASSED, %d SKIPPED, %d FAILED\n", passes,
+  skips, errors);
return errors ? EXIT_FAILURE : EXIT_SUCCESS;
 }
 
-- 
2.14.1



[PATCH bpf-next 3/4] selftests/bpf: Only run tests if !bpf_disabled

2018-02-14 Thread Joe Stringer
The "kernel.unprivileged_bpf_disabled" sysctl, if enabled, causes all
unprivileged tests to fail because it permanently disables unprivileged
BPF access for the currently running kernel. Skip the relevant tests if
the user attempts to run the testsuite with this sysctl enabled.

Signed-off-by: Joe Stringer 
---
 tools/testing/selftests/bpf/test_verifier.c | 26 +-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/bpf/test_verifier.c 
b/tools/testing/selftests/bpf/test_verifier.c
index 7ab02526c403..2971ba2829ac 100644
--- a/tools/testing/selftests/bpf/test_verifier.c
+++ b/tools/testing/selftests/bpf/test_verifier.c
@@ -57,6 +57,9 @@
 #define F_NEEDS_EFFICIENT_UNALIGNED_ACCESS (1 << 0)
 #define F_LOAD_WITH_STRICT_ALIGNMENT   (1 << 1)
 
+#define UNPRIV_SYSCTL "kernel/unprivileged_bpf_disabled"
+static bool unpriv_disabled = false;
+
 struct bpf_test {
const char *descr;
struct bpf_insn insns[MAX_INSNS];
@@ -11376,6 +11379,17 @@ static int set_admin(bool admin)
return ret;
 }
 
+static void get_unpriv_disabled()
+{
+   char buf[2];
+   FILE *fd;
+
+   fd = fopen("/proc/sys/"UNPRIV_SYSCTL, "r");
+   if (fgets(buf, 2, fd) == buf && atoi(buf))
+   unpriv_disabled = true;
+   fclose(fd);
+}
+
 static int do_test(bool unpriv, unsigned int from, unsigned int to)
 {
int i, passes = 0, errors = 0, skips = 0;
@@ -11386,7 +11400,10 @@ static int do_test(bool unpriv, unsigned int from, 
unsigned int to)
/* Program types that are not supported by non-root we
 * skip right away.
 */
-   if (!test->prog_type) {
+   if (!test->prog_type && unpriv_disabled) {
+   printf("#%d/u %s SKIP\n", i, test->descr);
+   skips++;
+   } else if (!test->prog_type) {
if (!unpriv)
set_admin(false);
printf("#%d/u %s ", i, test->descr);
@@ -11433,6 +11450,13 @@ int main(int argc, char **argv)
}
}
 
+   get_unpriv_disabled();
+   if (unpriv && unpriv_disabled) {
+   printf("Cannot run as unprivileged user with sysctl %s.\n",
+  UNPRIV_SYSCTL);
+   return EXIT_FAILURE;
+   }
+
setrlimit(RLIMIT_MEMLOCK, unpriv ?  : );
return do_test(unpriv, from, to);
 }
-- 
2.14.1



[PATCH bpf-next 4/4] bpf: Remove unused callee_saved array

2018-02-14 Thread Joe Stringer
This array appears to be completely unused, remove it.

Signed-off-by: Joe Stringer 
---
 kernel/bpf/verifier.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 5fb69a85d967..3c74b163eaeb 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -508,10 +508,6 @@ static struct bpf_verifier_state *push_stack(struct 
bpf_verifier_env *env,
 static const int caller_saved[CALLER_SAVED_REGS] = {
BPF_REG_0, BPF_REG_1, BPF_REG_2, BPF_REG_3, BPF_REG_4, BPF_REG_5
 };
-#define CALLEE_SAVED_REGS 5
-static const int callee_saved[CALLEE_SAVED_REGS] = {
-   BPF_REG_6, BPF_REG_7, BPF_REG_8, BPF_REG_9
-};
 
 static void __mark_reg_not_init(struct bpf_reg_state *reg);
 
-- 
2.14.1



[PATCH bpf-next 0/4] Misc test usability improvements & cleanup

2018-02-14 Thread Joe Stringer
This is series makes some minor changes primarily focused on making it easier
to understand why test_verifier is failing a test. This includes printing the
observed output when a test fails in a different way than expected, or when
unprivileged tests fail due to sysctl kernel.unprivileged_bpf_disabled=1. The
last patch removes some apparently dead code.

Joe Stringer (4):
  selftests/bpf: Print unexpected output on fail
  selftests/bpf: Count tests skipped by unpriv
  selftests/bpf: Only run tests if !bpf_disabled
  bpf: Remove unused callee_saved array

 kernel/bpf/verifier.c   |  4 ---
 tools/testing/selftests/bpf/test_verifier.c | 39 +
 2 files changed, 34 insertions(+), 9 deletions(-)

-- 
2.14.1



[PATCH bpf-next 1/4] selftests/bpf: Print unexpected output on fail

2018-02-14 Thread Joe Stringer
This makes it easier to debug off-hand when the error message isn't
exactly as expected.

Signed-off-by: Joe Stringer 
---
 tools/testing/selftests/bpf/test_verifier.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/bpf/test_verifier.c 
b/tools/testing/selftests/bpf/test_verifier.c
index c0f16e93f9bd..6cf9bd6f08b7 100644
--- a/tools/testing/selftests/bpf/test_verifier.c
+++ b/tools/testing/selftests/bpf/test_verifier.c
@@ -11291,7 +11291,8 @@ static void do_test_single(struct bpf_test *test, bool 
unpriv,
goto fail_log;
}
if (!strstr(bpf_vlog, expected_err) && !reject_from_alignment) {
-   printf("FAIL\nUnexpected error message!\n");
+   printf("FAIL\nUnexpected error message!\n\tEXP: 
%s\n\tRES: %s\n",
+ expected_err, bpf_vlog);
goto fail_log;
}
}
-- 
2.14.1



Re: [PATCH iproute2-next 0/9] ipaddress: Make print_linkinfo_brief() static

2018-02-14 Thread Serhey Popovych
David Ahern wrote:
> On 2/14/18 1:09 PM, Serhey Popovych wrote:
> 
>>
>> Any comments on this series? Should I perform some additional testing?
>>
>>
> 
> I thought I had applied them. Can you re-send and cc me?
> 
Done. v2 is broken due to missing subject line. v3 is ready.




signature.asc
Description: OpenPGP digital signature


Re: [PATCH V2 net-next 4/7] rds: support for zcopy completion notification

2018-02-14 Thread Santosh Shilimkar

On 2/14/2018 1:25 PM, Sowmini Varadhan wrote:

On (02/14/18 13:10), Santosh Shilimkar wrote:

RDS support true zero copy already with RDMA transport so some of
this code can easily get confused.


btw, another way to solve this is to have the RDMA code use the
suffix "rdma" (which is what it really is) as needed.


And same breath,here zcopy is No message from user ;-)
ZCOPY is otherwise often tied with RDMA directly.

Renaming churns are not that useful and I definitely agree
with what Dave said if it was renaming change to the
existing code like what you are suggesting with 'rdma'

Anyways I don't want to contest this too much since I can
follow that code and know what each does and means :-)

The comment was long term readability perspective for
some one completely new reading the code and being able to
distinguish the different modes.

Regards,
Santosh


[PATCH iproute2-next v3 7/9] utils: Introduce and use get_ifname_rta()

2018-02-14 Thread Serhey Popovych
Be consistent in handling of IFLA_IFNAME attribute in all places: if
there is no attribute report bug to stderr and use ll_idx_n2a() as
last measure to get name in "if%u" format instead of "".

Use check_ifname() to validate network device name: this catches both
unexpected return from kernel and ll_idx_n2a().

Signed-off-by: Serhey Popovych 
---
 bridge/link.c   |8 
 include/utils.h |1 +
 ip/ipaddress.c  |   20 
 lib/utils.c |   19 +++
 4 files changed, 32 insertions(+), 16 deletions(-)

diff --git a/bridge/link.c b/bridge/link.c
index 870ebe0..a11cbb1 100644
--- a/bridge/link.c
+++ b/bridge/link.c
@@ -99,9 +99,10 @@ int print_linkinfo(const struct sockaddr_nl *who,
   struct nlmsghdr *n, void *arg)
 {
FILE *fp = arg;
-   int len = n->nlmsg_len;
struct ifinfomsg *ifi = NLMSG_DATA(n);
struct rtattr *tb[IFLA_MAX+1];
+   int len = n->nlmsg_len;
+   const char *name;
 
len -= NLMSG_LENGTH(sizeof(*ifi));
if (len < 0) {
@@ -117,10 +118,9 @@ int print_linkinfo(const struct sockaddr_nl *who,
 
parse_rtattr_flags(tb, IFLA_MAX, IFLA_RTA(ifi), len, NLA_F_NESTED);
 
-   if (tb[IFLA_IFNAME] == NULL) {
-   fprintf(stderr, "BUG: nil ifname\n");
+   name = get_ifname_rta(ifi->ifi_index, tb[IFLA_IFNAME]);
+   if (!name)
return -1;
-   }
 
if (n->nlmsg_type == RTM_DELLINK)
fprintf(fp, "Deleted ");
diff --git a/include/utils.h b/include/utils.h
index 867e540..84ca873 100644
--- a/include/utils.h
+++ b/include/utils.h
@@ -183,6 +183,7 @@ void duparg(const char *, const char *) 
__attribute__((noreturn));
 void duparg2(const char *, const char *) __attribute__((noreturn));
 int check_ifname(const char *);
 int get_ifname(char *, const char *);
+const char *get_ifname_rta(int ifindex, const struct rtattr *rta);
 int matches(const char *arg, const char *pattern);
 int inet_addr_match(const inet_prefix *a, const inet_prefix *b, int bits);
 int inet_addr_match_rta(const inet_prefix *m, const struct rtattr *rta);
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index 1b4586c..670d8e0 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -776,12 +776,10 @@ int print_linkinfo_brief(const struct sockaddr_nl *who,
return -1;
 
parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
-   if (tb[IFLA_IFNAME] == NULL) {
-   fprintf(stderr, "BUG: device with ifindex %d has nil ifname\n", 
ifi->ifi_index);
-   name = ll_idx_n2a(ifi->ifi_index);
-   } else {
-   name = rta_getattr_str(tb[IFLA_IFNAME]);
-   }
+
+   name = get_ifname_rta(ifi->ifi_index, tb[IFLA_IFNAME]);
+   if (!name)
+   return -1;
 
if (filter.label &&
(!filter.family || filter.family == AF_PACKET) &&
@@ -903,12 +901,10 @@ int print_linkinfo(const struct sockaddr_nl *who,
return -1;
 
parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
-   if (tb[IFLA_IFNAME] == NULL) {
-   fprintf(stderr, "BUG: device with ifindex %d has nil ifname\n", 
ifi->ifi_index);
-   name = ll_idx_n2a(ifi->ifi_index);
-   } else {
-   name = rta_getattr_str(tb[IFLA_IFNAME]);
-   }
+
+   name = get_ifname_rta(ifi->ifi_index, tb[IFLA_IFNAME]);
+   if (!name)
+   return -1;
 
if (filter.label &&
(!filter.family || filter.family == AF_PACKET) &&
diff --git a/lib/utils.c b/lib/utils.c
index d86c2ee..572d42a 100644
--- a/lib/utils.c
+++ b/lib/utils.c
@@ -871,6 +871,25 @@ int get_ifname(char *buf, const char *name)
return ret;
 }
 
+const char *get_ifname_rta(int ifindex, const struct rtattr *rta)
+{
+   const char *name;
+
+   if (rta) {
+   name = rta_getattr_str(rta);
+   } else {
+   fprintf(stderr,
+   "BUG: device with ifindex %d has nil ifname\n",
+   ifindex);
+   name = ll_idx_n2a(ifindex);
+   }
+
+   if (check_ifname(name))
+   return NULL;
+
+   return name;
+}
+
 int matches(const char *cmd, const char *pattern)
 {
int len = strlen(cmd);
-- 
1.7.10.4



[PATCH iproute2-next v3 5/9] ipaddress: Simplify print_linkinfo_brief() and it's usage

2018-02-14 Thread Serhey Popovych
Simplify calling code in ipaddr_list_flush_or_save() by introducing
intermediate variable of @struct nlmsghdr, drop duplicated code:
print_linkinfo_brief() never returns values other than <= 0 so we can
move print_selected_addrinfo() outside of each block.

Signed-off-by: Serhey Popovych 
---
 ip/ipaddress.c |   31 ++-
 1 file changed, 14 insertions(+), 17 deletions(-)

diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index 6ada993..1b4586c 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -753,7 +753,7 @@ static void print_link_stats(FILE *fp, struct nlmsghdr *n)
 }
 
 int print_linkinfo_brief(const struct sockaddr_nl *who,
-   struct nlmsghdr *n, void *arg)
+struct nlmsghdr *n, void *arg)
 {
FILE *fp = (FILE *)arg;
struct ifinfomsg *ifi = NLMSG_DATA(n);
@@ -2012,24 +2012,21 @@ static int ipaddr_list_flush_or_save(int argc, char 
**argv, int action)
ipaddr_filter(, ainfo);
 
for (l = linfo.head; l; l = l->next) {
-   int res = 0;
-   struct ifinfomsg *ifi = NLMSG_DATA(>h);
+   struct nlmsghdr *n = >h;
+   struct ifinfomsg *ifi = NLMSG_DATA(n);
+   int res;
 
open_json_object(NULL);
-   if (brief) {
-   if (print_linkinfo_brief(NULL, >h, stdout) == 0)
-   if (filter.family != AF_PACKET)
-   print_selected_addrinfo(ifi,
-   ainfo->head,
-   stdout);
-   } else if (no_link ||
-  (res = print_linkinfo(NULL, >h, stdout)) >= 0) {
-   if (filter.family != AF_PACKET)
-   print_selected_addrinfo(ifi,
-   ainfo->head, stdout);
-   if (res > 0 && !do_link && show_stats)
-   print_link_stats(stdout, >h);
-   }
+   if (brief)
+   res = print_linkinfo_brief(NULL, n, stdout);
+   else if (no_link)
+   res = 0;
+   else
+   res = print_linkinfo(NULL, n, stdout);
+   if (res >= 0 && filter.family != AF_PACKET)
+   print_selected_addrinfo(ifi, ainfo->head, stdout);
+   if (res > 0 && !do_link && show_stats)
+   print_link_stats(stdout, n);
close_json_object();
}
fflush(stdout);
-- 
1.7.10.4



[PATCH iproute2-next v3 3/9] utils: Reimplement ll_idx_n2a() and introduce ll_idx_a2n()

2018-02-14 Thread Serhey Popovych
Now all users of ll_idx_n2a() replaced with ll_index_to_name() we can
move it's functionality to ll_index_to_name() and implement index to
name conversion using snprintf() and "if%u".

Use %u specifier in "if%..." template consistently: network device
indexes are always greather than zero.

Also introduce ll_idx_n2a() conterpart: ll_idx_a2n() that is used
to translate name of the "if%u" form to index using sscanf().

Signed-off-by: Serhey Popovych 
---
 include/ll_map.h |4 +++-
 lib/ll_map.c |   31 +--
 2 files changed, 24 insertions(+), 11 deletions(-)

diff --git a/include/ll_map.h b/include/ll_map.h
index c8474e6..8546ff9 100644
--- a/include/ll_map.h
+++ b/include/ll_map.h
@@ -8,9 +8,11 @@ int ll_remember_index(const struct sockaddr_nl *who,
 void ll_init_map(struct rtnl_handle *rth);
 unsigned ll_name_to_index(const char *name);
 const char *ll_index_to_name(unsigned idx);
-const char *ll_idx_n2a(unsigned idx, char *buf);
 int ll_index_to_type(unsigned idx);
 int ll_index_to_flags(unsigned idx);
 unsigned namehash(const char *str);
 
+const char *ll_idx_n2a(unsigned int idx);
+unsigned int ll_idx_a2n(const char *name);
+
 #endif /* __LL_MAP_H__ */
diff --git a/lib/ll_map.c b/lib/ll_map.c
index f65614f..0afe689 100644
--- a/lib/ll_map.c
+++ b/lib/ll_map.c
@@ -136,8 +136,26 @@ int ll_remember_index(const struct sockaddr_nl *who,
return 0;
 }
 
-const char *ll_idx_n2a(unsigned idx, char *buf)
+const char *ll_idx_n2a(unsigned int idx)
 {
+   static char buf[IFNAMSIZ];
+
+   snprintf(buf, sizeof(buf), "if%u", idx);
+   return buf;
+}
+
+unsigned int ll_idx_a2n(const char *name)
+{
+   unsigned int idx;
+
+   if (sscanf(name, "if%u", ) != 1)
+   return 0;
+   return idx;
+}
+
+const char *ll_index_to_name(unsigned int idx)
+{
+   static char buf[IFNAMSIZ];
const struct ll_cache *im;
 
if (idx == 0)
@@ -148,18 +166,11 @@ const char *ll_idx_n2a(unsigned idx, char *buf)
return im->name;
 
if (if_indextoname(idx, buf) == NULL)
-   snprintf(buf, IFNAMSIZ, "if%d", idx);
+   snprintf(buf, IFNAMSIZ, "if%u", idx);
 
return buf;
 }
 
-const char *ll_index_to_name(unsigned idx)
-{
-   static char nbuf[IFNAMSIZ];
-
-   return ll_idx_n2a(idx, nbuf);
-}
-
 int ll_index_to_type(unsigned idx)
 {
const struct ll_cache *im;
@@ -196,7 +207,7 @@ unsigned ll_name_to_index(const char *name)
 
idx = if_nametoindex(name);
if (idx == 0)
-   sscanf(name, "if%u", );
+   idx = ll_idx_a2n(name);
return idx;
 }
 
-- 
1.7.10.4



[PATCH iproute2-next v3 8/9] utils: Introduce and use print_name_and_link() to print name@link

2018-02-14 Thread Serhey Popovych
There is at least three places implementing same things: two in
ipaddress.c print_linkinfo() & print_linkinfo_brief() and one in
bridge/link.c.

They are diverge from each other very little: bridge/link.c does not
support JSON output at the moment and print_linkinfo_brief() does not
handle IFLA_LINK_NETNS case.

Introduce and use print_name_and_link() routine to handle name@link
output in all possible variations; respect IFLA_LINK_NETNS attribute to
handle case when link is in different namespace; use ll_idx_n2a() for
interface name instead of "" to share logic with other code (e.g.
ll_name_to_index() and ll_index_to_name()) supporting such template.

Signed-off-by: Serhey Popovych 
---
 bridge/link.c   |   13 +++--
 include/utils.h |4 
 ip/ipaddress.c  |   44 ++--
 lib/utils.c |   49 +
 4 files changed, 58 insertions(+), 52 deletions(-)

diff --git a/bridge/link.c b/bridge/link.c
index a11cbb1..90c9734 100644
--- a/bridge/link.c
+++ b/bridge/link.c
@@ -125,20 +125,13 @@ int print_linkinfo(const struct sockaddr_nl *who,
if (n->nlmsg_type == RTM_DELLINK)
fprintf(fp, "Deleted ");
 
-   fprintf(fp, "%d: %s ", ifi->ifi_index,
-   tb[IFLA_IFNAME] ? rta_getattr_str(tb[IFLA_IFNAME]) : "");
+   fprintf(fp, "%d: ", ifi->ifi_index);
+
+   print_name_and_link("%s: ", COLOR_NONE, name, tb);
 
if (tb[IFLA_OPERSTATE])
print_operstate(fp, rta_getattr_u8(tb[IFLA_OPERSTATE]));
 
-   if (tb[IFLA_LINK]) {
-   int iflink = rta_getattr_u32(tb[IFLA_LINK]);
-
-   fprintf(fp, "@%s: ",
-   iflink ? ll_index_to_name(iflink) : "NONE");
-   } else
-   fprintf(fp, ": ");
-
print_link_flags(fp, ifi->ifi_flags);
 
if (tb[IFLA_MTU])
diff --git a/include/utils.h b/include/utils.h
index 84ca873..75ddb4a 100644
--- a/include/utils.h
+++ b/include/utils.h
@@ -12,6 +12,7 @@
 #include "libnetlink.h"
 #include "ll_map.h"
 #include "rtm_map.h"
+#include "json_print.h"
 
 extern int preferred_family;
 extern int human_readable;
@@ -250,6 +251,9 @@ void print_escape_buf(const __u8 *buf, size_t len, const 
char *escape);
 int print_timestamp(FILE *fp);
 void print_nlmsg_timestamp(FILE *fp, const struct nlmsghdr *n);
 
+unsigned int print_name_and_link(const char *fmt, enum color_attr color,
+const char *name, struct rtattr *tb[]);
+
 #define BIT(nr) (1UL << (nr))
 
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index 670d8e0..e14a59e 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -760,7 +760,6 @@ int print_linkinfo_brief(const struct sockaddr_nl *who,
struct rtattr *tb[IFLA_MAX+1];
int len = n->nlmsg_len;
const char *name;
-   char buf[32] = { 0, };
unsigned int m_flag = 0;
 
if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK)
@@ -810,25 +809,7 @@ int print_linkinfo_brief(const struct sockaddr_nl *who,
if (n->nlmsg_type == RTM_DELLINK)
print_bool(PRINT_ANY, "deleted", "Deleted ", true);
 
-   if (tb[IFLA_LINK]) {
-   int iflink = rta_getattr_u32(tb[IFLA_LINK]);
-
-   if (iflink == 0) {
-   snprintf(buf, sizeof(buf), "%s@NONE", name);
-   print_null(PRINT_JSON, "link", NULL, NULL);
-   } else {
-   const char *link = ll_index_to_name(iflink);
-
-   print_string(PRINT_JSON, "link", NULL, link);
-   snprintf(buf, sizeof(buf), "%s@%s", name, link);
-   m_flag = ll_index_to_flags(iflink);
-   m_flag = !(m_flag & IFF_UP);
-   }
-   } else
-   snprintf(buf, sizeof(buf), "%s", name);
-
-   print_string(PRINT_FP, NULL, "%-16s ", buf);
-   print_string(PRINT_JSON, "ifname", NULL, name);
+   m_flag = print_name_and_link("%-16s ", COLOR_NONE, name, tb);
 
if (tb[IFLA_OPERSTATE])
print_operstate(fp, rta_getattr_u8(tb[IFLA_OPERSTATE]));
@@ -936,29 +917,8 @@ int print_linkinfo(const struct sockaddr_nl *who,
print_bool(PRINT_ANY, "deleted", "Deleted ", true);
 
print_int(PRINT_ANY, "ifindex", "%d: ", ifi->ifi_index);
-   print_color_string(PRINT_ANY, COLOR_IFNAME, "ifname", "%s", name);
-
-   if (tb[IFLA_LINK]) {
-   int iflink = rta_getattr_u32(tb[IFLA_LINK]);
 
-   if (iflink == 0)
-   print_null(PRINT_ANY, "link", "@%s: ", "NONE");
-   else {
-   if (tb[IFLA_LINK_NETNSID])
-   print_int(PRINT_ANY,
- "link_index", "@if%d: ", iflink);
-   else {
-   

[PATCH iproute2-next v3 2/9] ipaddress: ll_map: Replace ll_idx_n2a() with ll_index_to_name()

2018-02-14 Thread Serhey Popovych
There is no reentrancy as well as deferred result usage for all cases
where ll_idx_n2a() being used: it is safe to use ll_index_to_name() that
internally calls ll_idx_n2a() with static buffer to hold result.

Signed-off-by: Serhey Popovych 
---
 ip/ipaddress.c |   14 +-
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index ad69d09..6b8295d 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -813,14 +813,13 @@ int print_linkinfo_brief(const struct sockaddr_nl *who,
print_bool(PRINT_ANY, "deleted", "Deleted ", true);
 
if (tb[IFLA_LINK]) {
-   SPRINT_BUF(b1);
int iflink = rta_getattr_u32(tb[IFLA_LINK]);
 
if (iflink == 0) {
snprintf(buf, sizeof(buf), "%s@NONE", name);
print_null(PRINT_JSON, "link", NULL, NULL);
} else {
-   const char *link = ll_idx_n2a(iflink, b1);
+   const char *link = ll_index_to_name(iflink);
 
print_string(PRINT_JSON, "link", NULL, link);
snprintf(buf, sizeof(buf), "%s@%s", name, link);
@@ -957,12 +956,10 @@ int print_linkinfo(const struct sockaddr_nl *who,
print_int(PRINT_ANY,
  "link_index", "@if%d: ", iflink);
else {
-   SPRINT_BUF(b1);
-
print_string(PRINT_ANY,
 "link",
 "@%s: ",
-ll_idx_n2a(iflink, b1));
+ll_index_to_name(iflink));
m_flag = ll_index_to_flags(iflink);
m_flag = !(m_flag & IFF_UP);
}
@@ -984,12 +981,12 @@ int print_linkinfo(const struct sockaddr_nl *who,
 "qdisc %s ",
 rta_getattr_str(tb[IFLA_QDISC]));
if (tb[IFLA_MASTER]) {
-   SPRINT_BUF(b1);
+   int master = rta_getattr_u32(tb[IFLA_MASTER]);
 
print_string(PRINT_ANY,
 "master",
 "master %s ",
-ll_idx_n2a(rta_getattr_u32(tb[IFLA_MASTER]), b1));
+ll_index_to_name(master));
}
 
if (tb[IFLA_OPERSTATE])
@@ -1308,7 +1305,6 @@ static int get_filter(const char *arg)
 static int ifa_label_match_rta(int ifindex, const struct rtattr *rta)
 {
const char *label;
-   SPRINT_BUF(b1);
 
if (!filter.label)
return 0;
@@ -1316,7 +1312,7 @@ static int ifa_label_match_rta(int ifindex, const struct 
rtattr *rta)
if (rta)
label = RTA_DATA(rta);
else
-   label = ll_idx_n2a(ifindex, b1);
+   label = ll_index_to_name(ifindex);
 
return fnmatch(filter.label, label, 0);
 }
-- 
1.7.10.4



[PATCH iproute2-next v3 6/9] lib: Correct object file dependencies

2018-02-14 Thread Serhey Popovych
Neither internal libnetlink nor libgenl depends on ll_map.o: prepare for
upcoming changes that brings much more cleaner dependency between
utils.o and ll_map.o.

Signed-off-by: Serhey Popovych 
---
 lib/Makefile |4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/Makefile b/lib/Makefile
index 7b34ed5..bab8cbf 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -3,11 +3,11 @@ include ../config.mk
 
 CFLAGS += -fPIC
 
-UTILOBJ = utils.o rt_names.o ll_types.o ll_proto.o ll_addr.o \
+UTILOBJ = utils.o rt_names.o ll_map.o ll_types.o ll_proto.o ll_addr.o \
inet_proto.o namespace.o json_writer.o json_print.o \
names.o color.o bpf.o exec.o fs.o
 
-NLOBJ=libgenl.o ll_map.o libnetlink.o
+NLOBJ=libgenl.o libnetlink.o
 
 all: libnetlink.a libutil.a
 
-- 
1.7.10.4



[PATCH iproute2-next v3 0/9] ipaddress: Make print_linkinfo_brief() static

2018-02-14 Thread Serhey Popovych
With this series I propose to make print_linkinfo_brief() static in
favor of print_linkinfo() as single point for linkinfo printing.

Changes presented with this series tested using following script:

\#!/bin/bash

iproute2_dir="$1"
iface='eth0.2'

pushd "$iproute2_dir" &>/dev/null

for i in new old; do
DIR="/tmp/$i"
mkdir -p "$DIR"

ln -snf ip.$i ip/ip

# normal
ip/ip link show  >"$DIR/ip-link-show"
ip/ip -4 addr show   >"$DIR/ip-4-addr-show"
ip/ip -6 addr show   >"$DIR/ip-6-addr-show"
ip/ip addr show dev "$iface" >"$DIR/ip-addr-show-$iface"

# brief
ip/ip -br link show  >"$DIR/ip-br-link-show"
ip/ip -br -4 addr show   >"$DIR/ip-br-4-addr-show"
ip/ip -br -6 addr show   >"$DIR/ip-br-6-addr-show"
ip/ip -br addr show dev "$iface" >"$DIR/ip-br-addr-show-$iface"
done
rm -f ip/ip

diff -urN /tmp/{old,new} |sed -n -Ee'/^(-{3}|\+{3})[[:space:]]+/!p'
rc=$?

popd &>/dev/null
exit $rc

Expected results : 
Actual results   : 

Although test coverage is far from ideal in my opinion it covers most
important aspects of the changes presented by the series.

All this work is done in prepare of iplink_get() enhancements to support
attribute parse that finally will be used to simplify ip/tunnel
RTM_GETLINK code.

As always reviews, comments, suggestions and criticism is welcome.

v3
  Fixed subject line.

v2
  Rebased to current iproute2-next/master. No changes.

Thanks,
Serhii

Serhey Popovych (9):
  ipaddress: Abstract IFA_LABEL matching code
  ipaddress: ll_map: Replace ll_idx_n2a() with ll_index_to_name()
  utils: Reimplement ll_idx_n2a() and introduce ll_idx_a2n()
  ipaddress: Improve print_linkinfo()
  ipaddress: Simplify print_linkinfo_brief() and it's usage
  lib: Correct object file dependencies
  utils: Introduce and use get_ifname_rta()
  utils: Introduce and use print_name_and_link() to print name@link
  ipaddress: Make print_linkinfo_brief() static

 bridge/link.c|   21 ++---
 include/ll_map.h |4 +-
 include/utils.h  |5 ++
 ip/ip_common.h   |2 -
 ip/ipaddress.c   |  224 ++
 ip/iplink.c  |5 +-
 lib/Makefile |4 +-
 lib/ll_map.c |   31 +---
 lib/utils.c  |   68 +
 9 files changed, 162 insertions(+), 202 deletions(-)

-- 
1.7.10.4



[PATCH iproute2-next v3 9/9] ipaddress: Make print_linkinfo_brief() static

2018-02-14 Thread Serhey Popovych
It shares lot of code with print_linkinfo(): drop duplicated part,
change parameters list, make it static and call from print_linkinfo()
after common path.

While there move SPRINT_BUF() to the function scope from blocks to
avoid duplication and use "%s" to print "\n" to help compiler optimize
exit for both print_linkinfo_brief() and normal paths.

Signed-off-by: Serhey Popovych 
---
 ip/ip_common.h |2 --
 ip/ipaddress.c |   76 
 ip/iplink.c|5 +---
 3 files changed, 11 insertions(+), 72 deletions(-)

diff --git a/ip/ip_common.h b/ip/ip_common.h
index 1397d99..e4e628b 100644
--- a/ip/ip_common.h
+++ b/ip/ip_common.h
@@ -29,8 +29,6 @@ struct link_filter {
 int get_operstate(const char *name);
 int print_linkinfo(const struct sockaddr_nl *who,
   struct nlmsghdr *n, void *arg);
-int print_linkinfo_brief(const struct sockaddr_nl *who,
-struct nlmsghdr *n, void *arg);
 int print_addrinfo(const struct sockaddr_nl *who,
   struct nlmsghdr *n, void *arg);
 int print_addrlabel(const struct sockaddr_nl *who,
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index e14a59e..e804487 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -752,63 +752,12 @@ static void print_link_stats(FILE *fp, struct nlmsghdr *n)
fprintf(fp, "%s", _SL_);
 }
 
-int print_linkinfo_brief(const struct sockaddr_nl *who,
-struct nlmsghdr *n, void *arg)
+static int print_linkinfo_brief(FILE *fp, const char *name,
+   const struct ifinfomsg *ifi,
+   struct rtattr *tb[])
 {
-   FILE *fp = (FILE *)arg;
-   struct ifinfomsg *ifi = NLMSG_DATA(n);
-   struct rtattr *tb[IFLA_MAX+1];
-   int len = n->nlmsg_len;
-   const char *name;
unsigned int m_flag = 0;
 
-   if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK)
-   return -1;
-
-   len -= NLMSG_LENGTH(sizeof(*ifi));
-   if (len < 0)
-   return -1;
-
-   if (filter.ifindex && ifi->ifi_index != filter.ifindex)
-   return -1;
-   if (filter.up && !(ifi->ifi_flags_UP))
-   return -1;
-
-   parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
-
-   name = get_ifname_rta(ifi->ifi_index, tb[IFLA_IFNAME]);
-   if (!name)
-   return -1;
-
-   if (filter.label &&
-   (!filter.family || filter.family == AF_PACKET) &&
-   fnmatch(filter.label, name, 0))
-   return -1;
-
-   if (tb[IFLA_GROUP]) {
-   int group = rta_getattr_u32(tb[IFLA_GROUP]);
-
-   if (filter.group != -1 && group != filter.group)
-   return -1;
-   }
-
-   if (tb[IFLA_MASTER]) {
-   int master = rta_getattr_u32(tb[IFLA_MASTER]);
-
-   if (filter.master > 0 && master != filter.master)
-   return -1;
-   } else if (filter.master > 0)
-   return -1;
-
-   if (filter.kind && match_link_kind(tb, filter.kind, 0))
-   return -1;
-
-   if (filter.slave_kind && match_link_kind(tb, filter.slave_kind, 1))
-   return -1;
-
-   if (n->nlmsg_type == RTM_DELLINK)
-   print_bool(PRINT_ANY, "deleted", "Deleted ", true);
-
m_flag = print_name_and_link("%-16s ", COLOR_NONE, name, tb);
 
if (tb[IFLA_OPERSTATE])
@@ -868,6 +817,7 @@ int print_linkinfo(const struct sockaddr_nl *who,
int len = n->nlmsg_len;
const char *name;
unsigned int m_flag = 0;
+   SPRINT_BUF(b1);
 
if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK)
return 0;
@@ -916,6 +866,9 @@ int print_linkinfo(const struct sockaddr_nl *who,
if (n->nlmsg_type == RTM_DELLINK)
print_bool(PRINT_ANY, "deleted", "Deleted ", true);
 
+   if (brief)
+   return print_linkinfo_brief(fp, name, ifi, tb);
+
print_int(PRINT_ANY, "ifindex", "%d: ", ifi->ifi_index);
 
m_flag = print_name_and_link("%s: ", COLOR_IFNAME, name, tb);
@@ -948,7 +901,6 @@ int print_linkinfo(const struct sockaddr_nl *who,
print_linkmode(fp, tb[IFLA_LINKMODE]);
 
if (tb[IFLA_GROUP]) {
-   SPRINT_BUF(b1);
int group = rta_getattr_u32(tb[IFLA_GROUP]);
 
print_string(PRINT_ANY,
@@ -964,8 +916,6 @@ int print_linkinfo(const struct sockaddr_nl *who,
print_link_event(fp, rta_getattr_u32(tb[IFLA_EVENT]));
 
if (!filter.family || filter.family == AF_PACKET || show_details) {
-   SPRINT_BUF(b1);
-
print_string(PRINT_FP, NULL, "%s", _SL_);
print_string(PRINT_ANY,
 "link_type",
@@ -1065,7 +1015,6 @@ int print_linkinfo(const struct sockaddr_nl *who,
 

[PATCH iproute2-next v3 1/9] ipaddress: Abstract IFA_LABEL matching code

2018-02-14 Thread Serhey Popovych
There at least two places in ip/ipaddress.c where we match IFA_LABEL
against filter.label if that is given.

Get rid of "common" if () statement for inet_addr_match_rta() and
ifa_label_match_rta(): it is not common because first will check for
filter.pfx.family != AF_UNSPEC inside and second for filter.label being
non NULL.

This allows us to further simplify down code and prepare for
ll_idx_n2a() replacement with ll_index_to_name() without 80 columns
checkpatch notice.

Signed-off-by: Serhey Popovych 
---
 ip/ipaddress.c |   57 +++-
 1 file changed, 27 insertions(+), 30 deletions(-)

diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index 6990b81..ad69d09 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -1305,6 +1305,22 @@ static int get_filter(const char *arg)
return 0;
 }
 
+static int ifa_label_match_rta(int ifindex, const struct rtattr *rta)
+{
+   const char *label;
+   SPRINT_BUF(b1);
+
+   if (!filter.label)
+   return 0;
+
+   if (rta)
+   label = RTA_DATA(rta);
+   else
+   label = ll_idx_n2a(ifindex, b1);
+
+   return fnmatch(filter.label, label, 0);
+}
+
 int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n,
   void *arg)
 {
@@ -1343,21 +1359,13 @@ int print_addrinfo(const struct sockaddr_nl *who, 
struct nlmsghdr *n,
return 0;
if ((filter.flags ^ ifa_flags) & filter.flagmask)
return 0;
-   if (filter.label) {
-   SPRINT_BUF(b1);
-   const char *label;
-
-   if (rta_tb[IFA_LABEL])
-   label = RTA_DATA(rta_tb[IFA_LABEL]);
-   else
-   label = ll_idx_n2a(ifa->ifa_index, b1);
-   if (fnmatch(filter.label, label, 0) != 0)
-   return 0;
-   }
 
if (filter.family && filter.family != ifa->ifa_family)
return 0;
 
+   if (ifa_label_match_rta(ifa->ifa_index, rta_tb[IFA_LABEL]))
+   return 0;
+
if (inet_addr_match_rta(, rta_tb[IFA_LOCAL]))
return 0;
 
@@ -1713,25 +1721,14 @@ static void ipaddr_filter(struct nlmsg_chain *linfo, 
struct nlmsg_chain *ainfo)
 
if ((filter.flags ^ ifa_flags) & filter.flagmask)
continue;
-   if (filter.pfx.family || filter.label) {
-   struct rtattr *rta =
-   tb[IFA_LOCAL] ? : tb[IFA_ADDRESS];
-
-   if (inet_addr_match_rta(, rta))
-   continue;
-
-   if (filter.label) {
-   SPRINT_BUF(b1);
-   const char *label;
-
-   if (tb[IFA_LABEL])
-   label = RTA_DATA(tb[IFA_LABEL]);
-   else
-   label = 
ll_idx_n2a(ifa->ifa_index, b1);
-   if (fnmatch(filter.label, label, 0) != 
0)
-   continue;
-   }
-   }
+
+   if (ifa_label_match_rta(ifa->ifa_index, tb[IFA_LABEL]))
+   continue;
+
+   if (!tb[IFA_LOCAL])
+   tb[IFA_LOCAL] = tb[IFA_ADDRESS];
+   if (inet_addr_match_rta(, tb[IFA_LOCAL]))
+   continue;
 
ok = 1;
break;
-- 
1.7.10.4



[PATCH iproute2-next v3 4/9] ipaddress: Improve print_linkinfo()

2018-02-14 Thread Serhey Popovych
There are few places to improve:

  1) return -1 when entry is filtered instead of zero, which means
 accept entry: ipaddress_list_flush_or_save() the only user of this

  2) use ll_idx_n2a() as last resort to translate name to index for
 "should never happen" cases when cache shouldn't be considered

  3) replace open coded access to IFLA_IFNAME attribute data by
 RTA_DATA() with rta_getattr_str()

  4) simplify ifname printing since name is never NULL, thanks to (2).

Signed-off-by: Serhey Popovych 
---
 ip/ipaddress.c |   30 +-
 1 file changed, 13 insertions(+), 17 deletions(-)

diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index 6b8295d..6ada993 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -778,14 +778,14 @@ int print_linkinfo_brief(const struct sockaddr_nl *who,
parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
if (tb[IFLA_IFNAME] == NULL) {
fprintf(stderr, "BUG: device with ifindex %d has nil ifname\n", 
ifi->ifi_index);
-   name = "";
+   name = ll_idx_n2a(ifi->ifi_index);
} else {
name = rta_getattr_str(tb[IFLA_IFNAME]);
}
 
if (filter.label &&
(!filter.family || filter.family == AF_PACKET) &&
-   fnmatch(filter.label, RTA_DATA(tb[IFLA_IFNAME]), 0))
+   fnmatch(filter.label, name, 0))
return -1;
 
if (tb[IFLA_GROUP]) {
@@ -887,6 +887,7 @@ int print_linkinfo(const struct sockaddr_nl *who,
struct ifinfomsg *ifi = NLMSG_DATA(n);
struct rtattr *tb[IFLA_MAX+1];
int len = n->nlmsg_len;
+   const char *name;
unsigned int m_flag = 0;
 
if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK)
@@ -897,18 +898,22 @@ int print_linkinfo(const struct sockaddr_nl *who,
return -1;
 
if (filter.ifindex && ifi->ifi_index != filter.ifindex)
-   return 0;
+   return -1;
if (filter.up && !(ifi->ifi_flags_UP))
-   return 0;
+   return -1;
 
parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
-   if (tb[IFLA_IFNAME] == NULL)
+   if (tb[IFLA_IFNAME] == NULL) {
fprintf(stderr, "BUG: device with ifindex %d has nil ifname\n", 
ifi->ifi_index);
+   name = ll_idx_n2a(ifi->ifi_index);
+   } else {
+   name = rta_getattr_str(tb[IFLA_IFNAME]);
+   }
 
if (filter.label &&
(!filter.family || filter.family == AF_PACKET) &&
-   fnmatch(filter.label, RTA_DATA(tb[IFLA_IFNAME]), 0))
-   return 0;
+   fnmatch(filter.label, name, 0))
+   return -1;
 
if (tb[IFLA_GROUP]) {
int group = rta_getattr_u32(tb[IFLA_GROUP]);
@@ -935,16 +940,7 @@ int print_linkinfo(const struct sockaddr_nl *who,
print_bool(PRINT_ANY, "deleted", "Deleted ", true);
 
print_int(PRINT_ANY, "ifindex", "%d: ", ifi->ifi_index);
-   if (tb[IFLA_IFNAME]) {
-   print_color_string(PRINT_ANY,
-  COLOR_IFNAME,
-  "ifname", "%s",
-  rta_getattr_str(tb[IFLA_IFNAME]));
-   } else {
-   print_null(PRINT_JSON, "ifname", NULL, NULL);
-   print_color_null(PRINT_FP, COLOR_IFNAME,
-"ifname", "%s", "");
-   }
+   print_color_string(PRINT_ANY, COLOR_IFNAME, "ifname", "%s", name);
 
if (tb[IFLA_LINK]) {
int iflink = rta_getattr_u32(tb[IFLA_LINK]);
-- 
1.7.10.4



Re: [PATCH iproute2-next v2 0/9] With this series I propose to make print_linkinfo_brief() static in

2018-02-14 Thread Serhey Popovych
Please ignore this series: wrong subject.

> Changes presented with this series tested using following script:
> 
> \#!/bin/bash
> 
> iproute2_dir="$1"
> iface='eth0.2'
> 
> pushd "$iproute2_dir" &>/dev/null
> 
> for i in new old; do
>   DIR="/tmp/$i"
>   mkdir -p "$DIR"
> 
>   ln -snf ip.$i ip/ip
> 
>   # normal
>   ip/ip link show  >"$DIR/ip-link-show"
>   ip/ip -4 addr show   >"$DIR/ip-4-addr-show"
>   ip/ip -6 addr show   >"$DIR/ip-6-addr-show"
>   ip/ip addr show dev "$iface" >"$DIR/ip-addr-show-$iface"
> 
>   # brief
>   ip/ip -br link show  >"$DIR/ip-br-link-show"
>   ip/ip -br -4 addr show   >"$DIR/ip-br-4-addr-show"
>   ip/ip -br -6 addr show   >"$DIR/ip-br-6-addr-show"
>   ip/ip -br addr show dev "$iface" >"$DIR/ip-br-addr-show-$iface"
> done
> rm -f ip/ip
> 
> diff -urN /tmp/{old,new} |sed -n -Ee'/^(-{3}|\+{3})[[:space:]]+/!p'
> rc=$?
> 
> popd &>/dev/null
> exit $rc
> 
> Expected results : 
> Actual results   : 
> 
> Although test coverage is far from ideal in my opinion it covers most
> important aspects of the changes presented by the series.
> 
> All this work is done in prepare of iplink_get() enhancements to support
> attribute parse that finally will be used to simplify ip/tunnel
> RTM_GETLINK code.
> 
> As always reviews, comments, suggestions and criticism is welcome.
> 
> v2
>   Rebased to current iproute2-next/master. No changes.
> 
> Thanks,
> Serhii
> 
> Serhey Popovych (9):
>   ipaddress: Abstract IFA_LABEL matching code
>   ipaddress: ll_map: Replace ll_idx_n2a() with ll_index_to_name()
>   utils: Reimplement ll_idx_n2a() and introduce ll_idx_a2n()
>   ipaddress: Improve print_linkinfo()
>   ipaddress: Simplify print_linkinfo_brief() and it's usage
>   lib: Correct object file dependencies
>   utils: Introduce and use get_ifname_rta()
>   utils: Introduce and use print_name_and_link() to print name@link
>   ipaddress: Make print_linkinfo_brief() static
> 
>  bridge/link.c|   21 ++---
>  include/ll_map.h |4 +-
>  include/utils.h  |5 ++
>  ip/ip_common.h   |2 -
>  ip/ipaddress.c   |  224 
> ++
>  ip/iplink.c  |5 +-
>  lib/Makefile |4 +-
>  lib/ll_map.c |   31 +---
>  lib/utils.c  |   68 +
>  9 files changed, 162 insertions(+), 202 deletions(-)
> 




signature.asc
Description: OpenPGP digital signature


[PATCH iproute2-next v2 2/9] ipaddress: ll_map: Replace ll_idx_n2a() with ll_index_to_name()

2018-02-14 Thread Serhey Popovych
There is no reentrancy as well as deferred result usage for all cases
where ll_idx_n2a() being used: it is safe to use ll_index_to_name() that
internally calls ll_idx_n2a() with static buffer to hold result.

Signed-off-by: Serhey Popovych 
---
 ip/ipaddress.c |   14 +-
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index ad69d09..6b8295d 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -813,14 +813,13 @@ int print_linkinfo_brief(const struct sockaddr_nl *who,
print_bool(PRINT_ANY, "deleted", "Deleted ", true);
 
if (tb[IFLA_LINK]) {
-   SPRINT_BUF(b1);
int iflink = rta_getattr_u32(tb[IFLA_LINK]);
 
if (iflink == 0) {
snprintf(buf, sizeof(buf), "%s@NONE", name);
print_null(PRINT_JSON, "link", NULL, NULL);
} else {
-   const char *link = ll_idx_n2a(iflink, b1);
+   const char *link = ll_index_to_name(iflink);
 
print_string(PRINT_JSON, "link", NULL, link);
snprintf(buf, sizeof(buf), "%s@%s", name, link);
@@ -957,12 +956,10 @@ int print_linkinfo(const struct sockaddr_nl *who,
print_int(PRINT_ANY,
  "link_index", "@if%d: ", iflink);
else {
-   SPRINT_BUF(b1);
-
print_string(PRINT_ANY,
 "link",
 "@%s: ",
-ll_idx_n2a(iflink, b1));
+ll_index_to_name(iflink));
m_flag = ll_index_to_flags(iflink);
m_flag = !(m_flag & IFF_UP);
}
@@ -984,12 +981,12 @@ int print_linkinfo(const struct sockaddr_nl *who,
 "qdisc %s ",
 rta_getattr_str(tb[IFLA_QDISC]));
if (tb[IFLA_MASTER]) {
-   SPRINT_BUF(b1);
+   int master = rta_getattr_u32(tb[IFLA_MASTER]);
 
print_string(PRINT_ANY,
 "master",
 "master %s ",
-ll_idx_n2a(rta_getattr_u32(tb[IFLA_MASTER]), b1));
+ll_index_to_name(master));
}
 
if (tb[IFLA_OPERSTATE])
@@ -1308,7 +1305,6 @@ static int get_filter(const char *arg)
 static int ifa_label_match_rta(int ifindex, const struct rtattr *rta)
 {
const char *label;
-   SPRINT_BUF(b1);
 
if (!filter.label)
return 0;
@@ -1316,7 +1312,7 @@ static int ifa_label_match_rta(int ifindex, const struct 
rtattr *rta)
if (rta)
label = RTA_DATA(rta);
else
-   label = ll_idx_n2a(ifindex, b1);
+   label = ll_index_to_name(ifindex);
 
return fnmatch(filter.label, label, 0);
 }
-- 
1.7.10.4



[PATCH iproute2-next v2 8/9] utils: Introduce and use print_name_and_link() to print name@link

2018-02-14 Thread Serhey Popovych
There is at least three places implementing same things: two in
ipaddress.c print_linkinfo() & print_linkinfo_brief() and one in
bridge/link.c.

They are diverge from each other very little: bridge/link.c does not
support JSON output at the moment and print_linkinfo_brief() does not
handle IFLA_LINK_NETNS case.

Introduce and use print_name_and_link() routine to handle name@link
output in all possible variations; respect IFLA_LINK_NETNS attribute to
handle case when link is in different namespace; use ll_idx_n2a() for
interface name instead of "" to share logic with other code (e.g.
ll_name_to_index() and ll_index_to_name()) supporting such template.

Signed-off-by: Serhey Popovych 
---
 bridge/link.c   |   13 +++--
 include/utils.h |4 
 ip/ipaddress.c  |   44 ++--
 lib/utils.c |   49 +
 4 files changed, 58 insertions(+), 52 deletions(-)

diff --git a/bridge/link.c b/bridge/link.c
index a11cbb1..90c9734 100644
--- a/bridge/link.c
+++ b/bridge/link.c
@@ -125,20 +125,13 @@ int print_linkinfo(const struct sockaddr_nl *who,
if (n->nlmsg_type == RTM_DELLINK)
fprintf(fp, "Deleted ");
 
-   fprintf(fp, "%d: %s ", ifi->ifi_index,
-   tb[IFLA_IFNAME] ? rta_getattr_str(tb[IFLA_IFNAME]) : "");
+   fprintf(fp, "%d: ", ifi->ifi_index);
+
+   print_name_and_link("%s: ", COLOR_NONE, name, tb);
 
if (tb[IFLA_OPERSTATE])
print_operstate(fp, rta_getattr_u8(tb[IFLA_OPERSTATE]));
 
-   if (tb[IFLA_LINK]) {
-   int iflink = rta_getattr_u32(tb[IFLA_LINK]);
-
-   fprintf(fp, "@%s: ",
-   iflink ? ll_index_to_name(iflink) : "NONE");
-   } else
-   fprintf(fp, ": ");
-
print_link_flags(fp, ifi->ifi_flags);
 
if (tb[IFLA_MTU])
diff --git a/include/utils.h b/include/utils.h
index 84ca873..75ddb4a 100644
--- a/include/utils.h
+++ b/include/utils.h
@@ -12,6 +12,7 @@
 #include "libnetlink.h"
 #include "ll_map.h"
 #include "rtm_map.h"
+#include "json_print.h"
 
 extern int preferred_family;
 extern int human_readable;
@@ -250,6 +251,9 @@ void print_escape_buf(const __u8 *buf, size_t len, const 
char *escape);
 int print_timestamp(FILE *fp);
 void print_nlmsg_timestamp(FILE *fp, const struct nlmsghdr *n);
 
+unsigned int print_name_and_link(const char *fmt, enum color_attr color,
+const char *name, struct rtattr *tb[]);
+
 #define BIT(nr) (1UL << (nr))
 
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index 670d8e0..e14a59e 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -760,7 +760,6 @@ int print_linkinfo_brief(const struct sockaddr_nl *who,
struct rtattr *tb[IFLA_MAX+1];
int len = n->nlmsg_len;
const char *name;
-   char buf[32] = { 0, };
unsigned int m_flag = 0;
 
if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK)
@@ -810,25 +809,7 @@ int print_linkinfo_brief(const struct sockaddr_nl *who,
if (n->nlmsg_type == RTM_DELLINK)
print_bool(PRINT_ANY, "deleted", "Deleted ", true);
 
-   if (tb[IFLA_LINK]) {
-   int iflink = rta_getattr_u32(tb[IFLA_LINK]);
-
-   if (iflink == 0) {
-   snprintf(buf, sizeof(buf), "%s@NONE", name);
-   print_null(PRINT_JSON, "link", NULL, NULL);
-   } else {
-   const char *link = ll_index_to_name(iflink);
-
-   print_string(PRINT_JSON, "link", NULL, link);
-   snprintf(buf, sizeof(buf), "%s@%s", name, link);
-   m_flag = ll_index_to_flags(iflink);
-   m_flag = !(m_flag & IFF_UP);
-   }
-   } else
-   snprintf(buf, sizeof(buf), "%s", name);
-
-   print_string(PRINT_FP, NULL, "%-16s ", buf);
-   print_string(PRINT_JSON, "ifname", NULL, name);
+   m_flag = print_name_and_link("%-16s ", COLOR_NONE, name, tb);
 
if (tb[IFLA_OPERSTATE])
print_operstate(fp, rta_getattr_u8(tb[IFLA_OPERSTATE]));
@@ -936,29 +917,8 @@ int print_linkinfo(const struct sockaddr_nl *who,
print_bool(PRINT_ANY, "deleted", "Deleted ", true);
 
print_int(PRINT_ANY, "ifindex", "%d: ", ifi->ifi_index);
-   print_color_string(PRINT_ANY, COLOR_IFNAME, "ifname", "%s", name);
-
-   if (tb[IFLA_LINK]) {
-   int iflink = rta_getattr_u32(tb[IFLA_LINK]);
 
-   if (iflink == 0)
-   print_null(PRINT_ANY, "link", "@%s: ", "NONE");
-   else {
-   if (tb[IFLA_LINK_NETNSID])
-   print_int(PRINT_ANY,
- "link_index", "@if%d: ", iflink);
-   else {
-   

[PATCH iproute2-next v2 1/9] ipaddress: Abstract IFA_LABEL matching code

2018-02-14 Thread Serhey Popovych
There at least two places in ip/ipaddress.c where we match IFA_LABEL
against filter.label if that is given.

Get rid of "common" if () statement for inet_addr_match_rta() and
ifa_label_match_rta(): it is not common because first will check for
filter.pfx.family != AF_UNSPEC inside and second for filter.label being
non NULL.

This allows us to further simplify down code and prepare for
ll_idx_n2a() replacement with ll_index_to_name() without 80 columns
checkpatch notice.

Signed-off-by: Serhey Popovych 
---
 ip/ipaddress.c |   57 +++-
 1 file changed, 27 insertions(+), 30 deletions(-)

diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index 6990b81..ad69d09 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -1305,6 +1305,22 @@ static int get_filter(const char *arg)
return 0;
 }
 
+static int ifa_label_match_rta(int ifindex, const struct rtattr *rta)
+{
+   const char *label;
+   SPRINT_BUF(b1);
+
+   if (!filter.label)
+   return 0;
+
+   if (rta)
+   label = RTA_DATA(rta);
+   else
+   label = ll_idx_n2a(ifindex, b1);
+
+   return fnmatch(filter.label, label, 0);
+}
+
 int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n,
   void *arg)
 {
@@ -1343,21 +1359,13 @@ int print_addrinfo(const struct sockaddr_nl *who, 
struct nlmsghdr *n,
return 0;
if ((filter.flags ^ ifa_flags) & filter.flagmask)
return 0;
-   if (filter.label) {
-   SPRINT_BUF(b1);
-   const char *label;
-
-   if (rta_tb[IFA_LABEL])
-   label = RTA_DATA(rta_tb[IFA_LABEL]);
-   else
-   label = ll_idx_n2a(ifa->ifa_index, b1);
-   if (fnmatch(filter.label, label, 0) != 0)
-   return 0;
-   }
 
if (filter.family && filter.family != ifa->ifa_family)
return 0;
 
+   if (ifa_label_match_rta(ifa->ifa_index, rta_tb[IFA_LABEL]))
+   return 0;
+
if (inet_addr_match_rta(, rta_tb[IFA_LOCAL]))
return 0;
 
@@ -1713,25 +1721,14 @@ static void ipaddr_filter(struct nlmsg_chain *linfo, 
struct nlmsg_chain *ainfo)
 
if ((filter.flags ^ ifa_flags) & filter.flagmask)
continue;
-   if (filter.pfx.family || filter.label) {
-   struct rtattr *rta =
-   tb[IFA_LOCAL] ? : tb[IFA_ADDRESS];
-
-   if (inet_addr_match_rta(, rta))
-   continue;
-
-   if (filter.label) {
-   SPRINT_BUF(b1);
-   const char *label;
-
-   if (tb[IFA_LABEL])
-   label = RTA_DATA(tb[IFA_LABEL]);
-   else
-   label = 
ll_idx_n2a(ifa->ifa_index, b1);
-   if (fnmatch(filter.label, label, 0) != 
0)
-   continue;
-   }
-   }
+
+   if (ifa_label_match_rta(ifa->ifa_index, tb[IFA_LABEL]))
+   continue;
+
+   if (!tb[IFA_LOCAL])
+   tb[IFA_LOCAL] = tb[IFA_ADDRESS];
+   if (inet_addr_match_rta(, tb[IFA_LOCAL]))
+   continue;
 
ok = 1;
break;
-- 
1.7.10.4



[PATCH iproute2-next v2 0/9] With this series I propose to make print_linkinfo_brief() static in

2018-02-14 Thread Serhey Popovych

Changes presented with this series tested using following script:

\#!/bin/bash

iproute2_dir="$1"
iface='eth0.2'

pushd "$iproute2_dir" &>/dev/null

for i in new old; do
DIR="/tmp/$i"
mkdir -p "$DIR"

ln -snf ip.$i ip/ip

# normal
ip/ip link show  >"$DIR/ip-link-show"
ip/ip -4 addr show   >"$DIR/ip-4-addr-show"
ip/ip -6 addr show   >"$DIR/ip-6-addr-show"
ip/ip addr show dev "$iface" >"$DIR/ip-addr-show-$iface"

# brief
ip/ip -br link show  >"$DIR/ip-br-link-show"
ip/ip -br -4 addr show   >"$DIR/ip-br-4-addr-show"
ip/ip -br -6 addr show   >"$DIR/ip-br-6-addr-show"
ip/ip -br addr show dev "$iface" >"$DIR/ip-br-addr-show-$iface"
done
rm -f ip/ip

diff -urN /tmp/{old,new} |sed -n -Ee'/^(-{3}|\+{3})[[:space:]]+/!p'
rc=$?

popd &>/dev/null
exit $rc

Expected results : 
Actual results   : 

Although test coverage is far from ideal in my opinion it covers most
important aspects of the changes presented by the series.

All this work is done in prepare of iplink_get() enhancements to support
attribute parse that finally will be used to simplify ip/tunnel
RTM_GETLINK code.

As always reviews, comments, suggestions and criticism is welcome.

v2
  Rebased to current iproute2-next/master. No changes.

Thanks,
Serhii

Serhey Popovych (9):
  ipaddress: Abstract IFA_LABEL matching code
  ipaddress: ll_map: Replace ll_idx_n2a() with ll_index_to_name()
  utils: Reimplement ll_idx_n2a() and introduce ll_idx_a2n()
  ipaddress: Improve print_linkinfo()
  ipaddress: Simplify print_linkinfo_brief() and it's usage
  lib: Correct object file dependencies
  utils: Introduce and use get_ifname_rta()
  utils: Introduce and use print_name_and_link() to print name@link
  ipaddress: Make print_linkinfo_brief() static

 bridge/link.c|   21 ++---
 include/ll_map.h |4 +-
 include/utils.h  |5 ++
 ip/ip_common.h   |2 -
 ip/ipaddress.c   |  224 ++
 ip/iplink.c  |5 +-
 lib/Makefile |4 +-
 lib/ll_map.c |   31 +---
 lib/utils.c  |   68 +
 9 files changed, 162 insertions(+), 202 deletions(-)

-- 
1.7.10.4



[PATCH iproute2-next v2 7/9] utils: Introduce and use get_ifname_rta()

2018-02-14 Thread Serhey Popovych
Be consistent in handling of IFLA_IFNAME attribute in all places: if
there is no attribute report bug to stderr and use ll_idx_n2a() as
last measure to get name in "if%u" format instead of "".

Use check_ifname() to validate network device name: this catches both
unexpected return from kernel and ll_idx_n2a().

Signed-off-by: Serhey Popovych 
---
 bridge/link.c   |8 
 include/utils.h |1 +
 ip/ipaddress.c  |   20 
 lib/utils.c |   19 +++
 4 files changed, 32 insertions(+), 16 deletions(-)

diff --git a/bridge/link.c b/bridge/link.c
index 870ebe0..a11cbb1 100644
--- a/bridge/link.c
+++ b/bridge/link.c
@@ -99,9 +99,10 @@ int print_linkinfo(const struct sockaddr_nl *who,
   struct nlmsghdr *n, void *arg)
 {
FILE *fp = arg;
-   int len = n->nlmsg_len;
struct ifinfomsg *ifi = NLMSG_DATA(n);
struct rtattr *tb[IFLA_MAX+1];
+   int len = n->nlmsg_len;
+   const char *name;
 
len -= NLMSG_LENGTH(sizeof(*ifi));
if (len < 0) {
@@ -117,10 +118,9 @@ int print_linkinfo(const struct sockaddr_nl *who,
 
parse_rtattr_flags(tb, IFLA_MAX, IFLA_RTA(ifi), len, NLA_F_NESTED);
 
-   if (tb[IFLA_IFNAME] == NULL) {
-   fprintf(stderr, "BUG: nil ifname\n");
+   name = get_ifname_rta(ifi->ifi_index, tb[IFLA_IFNAME]);
+   if (!name)
return -1;
-   }
 
if (n->nlmsg_type == RTM_DELLINK)
fprintf(fp, "Deleted ");
diff --git a/include/utils.h b/include/utils.h
index 867e540..84ca873 100644
--- a/include/utils.h
+++ b/include/utils.h
@@ -183,6 +183,7 @@ void duparg(const char *, const char *) 
__attribute__((noreturn));
 void duparg2(const char *, const char *) __attribute__((noreturn));
 int check_ifname(const char *);
 int get_ifname(char *, const char *);
+const char *get_ifname_rta(int ifindex, const struct rtattr *rta);
 int matches(const char *arg, const char *pattern);
 int inet_addr_match(const inet_prefix *a, const inet_prefix *b, int bits);
 int inet_addr_match_rta(const inet_prefix *m, const struct rtattr *rta);
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index 1b4586c..670d8e0 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -776,12 +776,10 @@ int print_linkinfo_brief(const struct sockaddr_nl *who,
return -1;
 
parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
-   if (tb[IFLA_IFNAME] == NULL) {
-   fprintf(stderr, "BUG: device with ifindex %d has nil ifname\n", 
ifi->ifi_index);
-   name = ll_idx_n2a(ifi->ifi_index);
-   } else {
-   name = rta_getattr_str(tb[IFLA_IFNAME]);
-   }
+
+   name = get_ifname_rta(ifi->ifi_index, tb[IFLA_IFNAME]);
+   if (!name)
+   return -1;
 
if (filter.label &&
(!filter.family || filter.family == AF_PACKET) &&
@@ -903,12 +901,10 @@ int print_linkinfo(const struct sockaddr_nl *who,
return -1;
 
parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
-   if (tb[IFLA_IFNAME] == NULL) {
-   fprintf(stderr, "BUG: device with ifindex %d has nil ifname\n", 
ifi->ifi_index);
-   name = ll_idx_n2a(ifi->ifi_index);
-   } else {
-   name = rta_getattr_str(tb[IFLA_IFNAME]);
-   }
+
+   name = get_ifname_rta(ifi->ifi_index, tb[IFLA_IFNAME]);
+   if (!name)
+   return -1;
 
if (filter.label &&
(!filter.family || filter.family == AF_PACKET) &&
diff --git a/lib/utils.c b/lib/utils.c
index d86c2ee..572d42a 100644
--- a/lib/utils.c
+++ b/lib/utils.c
@@ -871,6 +871,25 @@ int get_ifname(char *buf, const char *name)
return ret;
 }
 
+const char *get_ifname_rta(int ifindex, const struct rtattr *rta)
+{
+   const char *name;
+
+   if (rta) {
+   name = rta_getattr_str(rta);
+   } else {
+   fprintf(stderr,
+   "BUG: device with ifindex %d has nil ifname\n",
+   ifindex);
+   name = ll_idx_n2a(ifindex);
+   }
+
+   if (check_ifname(name))
+   return NULL;
+
+   return name;
+}
+
 int matches(const char *cmd, const char *pattern)
 {
int len = strlen(cmd);
-- 
1.7.10.4



[PATCH iproute2-next v2 4/9] ipaddress: Improve print_linkinfo()

2018-02-14 Thread Serhey Popovych
There are few places to improve:

  1) return -1 when entry is filtered instead of zero, which means
 accept entry: ipaddress_list_flush_or_save() the only user of this

  2) use ll_idx_n2a() as last resort to translate name to index for
 "should never happen" cases when cache shouldn't be considered

  3) replace open coded access to IFLA_IFNAME attribute data by
 RTA_DATA() with rta_getattr_str()

  4) simplify ifname printing since name is never NULL, thanks to (2).

Signed-off-by: Serhey Popovych 
---
 ip/ipaddress.c |   30 +-
 1 file changed, 13 insertions(+), 17 deletions(-)

diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index 6b8295d..6ada993 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -778,14 +778,14 @@ int print_linkinfo_brief(const struct sockaddr_nl *who,
parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
if (tb[IFLA_IFNAME] == NULL) {
fprintf(stderr, "BUG: device with ifindex %d has nil ifname\n", 
ifi->ifi_index);
-   name = "";
+   name = ll_idx_n2a(ifi->ifi_index);
} else {
name = rta_getattr_str(tb[IFLA_IFNAME]);
}
 
if (filter.label &&
(!filter.family || filter.family == AF_PACKET) &&
-   fnmatch(filter.label, RTA_DATA(tb[IFLA_IFNAME]), 0))
+   fnmatch(filter.label, name, 0))
return -1;
 
if (tb[IFLA_GROUP]) {
@@ -887,6 +887,7 @@ int print_linkinfo(const struct sockaddr_nl *who,
struct ifinfomsg *ifi = NLMSG_DATA(n);
struct rtattr *tb[IFLA_MAX+1];
int len = n->nlmsg_len;
+   const char *name;
unsigned int m_flag = 0;
 
if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK)
@@ -897,18 +898,22 @@ int print_linkinfo(const struct sockaddr_nl *who,
return -1;
 
if (filter.ifindex && ifi->ifi_index != filter.ifindex)
-   return 0;
+   return -1;
if (filter.up && !(ifi->ifi_flags_UP))
-   return 0;
+   return -1;
 
parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
-   if (tb[IFLA_IFNAME] == NULL)
+   if (tb[IFLA_IFNAME] == NULL) {
fprintf(stderr, "BUG: device with ifindex %d has nil ifname\n", 
ifi->ifi_index);
+   name = ll_idx_n2a(ifi->ifi_index);
+   } else {
+   name = rta_getattr_str(tb[IFLA_IFNAME]);
+   }
 
if (filter.label &&
(!filter.family || filter.family == AF_PACKET) &&
-   fnmatch(filter.label, RTA_DATA(tb[IFLA_IFNAME]), 0))
-   return 0;
+   fnmatch(filter.label, name, 0))
+   return -1;
 
if (tb[IFLA_GROUP]) {
int group = rta_getattr_u32(tb[IFLA_GROUP]);
@@ -935,16 +940,7 @@ int print_linkinfo(const struct sockaddr_nl *who,
print_bool(PRINT_ANY, "deleted", "Deleted ", true);
 
print_int(PRINT_ANY, "ifindex", "%d: ", ifi->ifi_index);
-   if (tb[IFLA_IFNAME]) {
-   print_color_string(PRINT_ANY,
-  COLOR_IFNAME,
-  "ifname", "%s",
-  rta_getattr_str(tb[IFLA_IFNAME]));
-   } else {
-   print_null(PRINT_JSON, "ifname", NULL, NULL);
-   print_color_null(PRINT_FP, COLOR_IFNAME,
-"ifname", "%s", "");
-   }
+   print_color_string(PRINT_ANY, COLOR_IFNAME, "ifname", "%s", name);
 
if (tb[IFLA_LINK]) {
int iflink = rta_getattr_u32(tb[IFLA_LINK]);
-- 
1.7.10.4



[PATCH iproute2-next v2 5/9] ipaddress: Simplify print_linkinfo_brief() and it's usage

2018-02-14 Thread Serhey Popovych
Simplify calling code in ipaddr_list_flush_or_save() by introducing
intermediate variable of @struct nlmsghdr, drop duplicated code:
print_linkinfo_brief() never returns values other than <= 0 so we can
move print_selected_addrinfo() outside of each block.

Signed-off-by: Serhey Popovych 
---
 ip/ipaddress.c |   31 ++-
 1 file changed, 14 insertions(+), 17 deletions(-)

diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index 6ada993..1b4586c 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -753,7 +753,7 @@ static void print_link_stats(FILE *fp, struct nlmsghdr *n)
 }
 
 int print_linkinfo_brief(const struct sockaddr_nl *who,
-   struct nlmsghdr *n, void *arg)
+struct nlmsghdr *n, void *arg)
 {
FILE *fp = (FILE *)arg;
struct ifinfomsg *ifi = NLMSG_DATA(n);
@@ -2012,24 +2012,21 @@ static int ipaddr_list_flush_or_save(int argc, char 
**argv, int action)
ipaddr_filter(, ainfo);
 
for (l = linfo.head; l; l = l->next) {
-   int res = 0;
-   struct ifinfomsg *ifi = NLMSG_DATA(>h);
+   struct nlmsghdr *n = >h;
+   struct ifinfomsg *ifi = NLMSG_DATA(n);
+   int res;
 
open_json_object(NULL);
-   if (brief) {
-   if (print_linkinfo_brief(NULL, >h, stdout) == 0)
-   if (filter.family != AF_PACKET)
-   print_selected_addrinfo(ifi,
-   ainfo->head,
-   stdout);
-   } else if (no_link ||
-  (res = print_linkinfo(NULL, >h, stdout)) >= 0) {
-   if (filter.family != AF_PACKET)
-   print_selected_addrinfo(ifi,
-   ainfo->head, stdout);
-   if (res > 0 && !do_link && show_stats)
-   print_link_stats(stdout, >h);
-   }
+   if (brief)
+   res = print_linkinfo_brief(NULL, n, stdout);
+   else if (no_link)
+   res = 0;
+   else
+   res = print_linkinfo(NULL, n, stdout);
+   if (res >= 0 && filter.family != AF_PACKET)
+   print_selected_addrinfo(ifi, ainfo->head, stdout);
+   if (res > 0 && !do_link && show_stats)
+   print_link_stats(stdout, n);
close_json_object();
}
fflush(stdout);
-- 
1.7.10.4



[PATCH iproute2-next v2 3/9] utils: Reimplement ll_idx_n2a() and introduce ll_idx_a2n()

2018-02-14 Thread Serhey Popovych
Now all users of ll_idx_n2a() replaced with ll_index_to_name() we can
move it's functionality to ll_index_to_name() and implement index to
name conversion using snprintf() and "if%u".

Use %u specifier in "if%..." template consistently: network device
indexes are always greather than zero.

Also introduce ll_idx_n2a() conterpart: ll_idx_a2n() that is used
to translate name of the "if%u" form to index using sscanf().

Signed-off-by: Serhey Popovych 
---
 include/ll_map.h |4 +++-
 lib/ll_map.c |   31 +--
 2 files changed, 24 insertions(+), 11 deletions(-)

diff --git a/include/ll_map.h b/include/ll_map.h
index c8474e6..8546ff9 100644
--- a/include/ll_map.h
+++ b/include/ll_map.h
@@ -8,9 +8,11 @@ int ll_remember_index(const struct sockaddr_nl *who,
 void ll_init_map(struct rtnl_handle *rth);
 unsigned ll_name_to_index(const char *name);
 const char *ll_index_to_name(unsigned idx);
-const char *ll_idx_n2a(unsigned idx, char *buf);
 int ll_index_to_type(unsigned idx);
 int ll_index_to_flags(unsigned idx);
 unsigned namehash(const char *str);
 
+const char *ll_idx_n2a(unsigned int idx);
+unsigned int ll_idx_a2n(const char *name);
+
 #endif /* __LL_MAP_H__ */
diff --git a/lib/ll_map.c b/lib/ll_map.c
index f65614f..0afe689 100644
--- a/lib/ll_map.c
+++ b/lib/ll_map.c
@@ -136,8 +136,26 @@ int ll_remember_index(const struct sockaddr_nl *who,
return 0;
 }
 
-const char *ll_idx_n2a(unsigned idx, char *buf)
+const char *ll_idx_n2a(unsigned int idx)
 {
+   static char buf[IFNAMSIZ];
+
+   snprintf(buf, sizeof(buf), "if%u", idx);
+   return buf;
+}
+
+unsigned int ll_idx_a2n(const char *name)
+{
+   unsigned int idx;
+
+   if (sscanf(name, "if%u", ) != 1)
+   return 0;
+   return idx;
+}
+
+const char *ll_index_to_name(unsigned int idx)
+{
+   static char buf[IFNAMSIZ];
const struct ll_cache *im;
 
if (idx == 0)
@@ -148,18 +166,11 @@ const char *ll_idx_n2a(unsigned idx, char *buf)
return im->name;
 
if (if_indextoname(idx, buf) == NULL)
-   snprintf(buf, IFNAMSIZ, "if%d", idx);
+   snprintf(buf, IFNAMSIZ, "if%u", idx);
 
return buf;
 }
 
-const char *ll_index_to_name(unsigned idx)
-{
-   static char nbuf[IFNAMSIZ];
-
-   return ll_idx_n2a(idx, nbuf);
-}
-
 int ll_index_to_type(unsigned idx)
 {
const struct ll_cache *im;
@@ -196,7 +207,7 @@ unsigned ll_name_to_index(const char *name)
 
idx = if_nametoindex(name);
if (idx == 0)
-   sscanf(name, "if%u", );
+   idx = ll_idx_a2n(name);
return idx;
 }
 
-- 
1.7.10.4



[PATCH iproute2-next v2 9/9] ipaddress: Make print_linkinfo_brief() static

2018-02-14 Thread Serhey Popovych
It shares lot of code with print_linkinfo(): drop duplicated part,
change parameters list, make it static and call from print_linkinfo()
after common path.

While there move SPRINT_BUF() to the function scope from blocks to
avoid duplication and use "%s" to print "\n" to help compiler optimize
exit for both print_linkinfo_brief() and normal paths.

Signed-off-by: Serhey Popovych 
---
 ip/ip_common.h |2 --
 ip/ipaddress.c |   76 
 ip/iplink.c|5 +---
 3 files changed, 11 insertions(+), 72 deletions(-)

diff --git a/ip/ip_common.h b/ip/ip_common.h
index 1397d99..e4e628b 100644
--- a/ip/ip_common.h
+++ b/ip/ip_common.h
@@ -29,8 +29,6 @@ struct link_filter {
 int get_operstate(const char *name);
 int print_linkinfo(const struct sockaddr_nl *who,
   struct nlmsghdr *n, void *arg);
-int print_linkinfo_brief(const struct sockaddr_nl *who,
-struct nlmsghdr *n, void *arg);
 int print_addrinfo(const struct sockaddr_nl *who,
   struct nlmsghdr *n, void *arg);
 int print_addrlabel(const struct sockaddr_nl *who,
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index e14a59e..e804487 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -752,63 +752,12 @@ static void print_link_stats(FILE *fp, struct nlmsghdr *n)
fprintf(fp, "%s", _SL_);
 }
 
-int print_linkinfo_brief(const struct sockaddr_nl *who,
-struct nlmsghdr *n, void *arg)
+static int print_linkinfo_brief(FILE *fp, const char *name,
+   const struct ifinfomsg *ifi,
+   struct rtattr *tb[])
 {
-   FILE *fp = (FILE *)arg;
-   struct ifinfomsg *ifi = NLMSG_DATA(n);
-   struct rtattr *tb[IFLA_MAX+1];
-   int len = n->nlmsg_len;
-   const char *name;
unsigned int m_flag = 0;
 
-   if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK)
-   return -1;
-
-   len -= NLMSG_LENGTH(sizeof(*ifi));
-   if (len < 0)
-   return -1;
-
-   if (filter.ifindex && ifi->ifi_index != filter.ifindex)
-   return -1;
-   if (filter.up && !(ifi->ifi_flags_UP))
-   return -1;
-
-   parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
-
-   name = get_ifname_rta(ifi->ifi_index, tb[IFLA_IFNAME]);
-   if (!name)
-   return -1;
-
-   if (filter.label &&
-   (!filter.family || filter.family == AF_PACKET) &&
-   fnmatch(filter.label, name, 0))
-   return -1;
-
-   if (tb[IFLA_GROUP]) {
-   int group = rta_getattr_u32(tb[IFLA_GROUP]);
-
-   if (filter.group != -1 && group != filter.group)
-   return -1;
-   }
-
-   if (tb[IFLA_MASTER]) {
-   int master = rta_getattr_u32(tb[IFLA_MASTER]);
-
-   if (filter.master > 0 && master != filter.master)
-   return -1;
-   } else if (filter.master > 0)
-   return -1;
-
-   if (filter.kind && match_link_kind(tb, filter.kind, 0))
-   return -1;
-
-   if (filter.slave_kind && match_link_kind(tb, filter.slave_kind, 1))
-   return -1;
-
-   if (n->nlmsg_type == RTM_DELLINK)
-   print_bool(PRINT_ANY, "deleted", "Deleted ", true);
-
m_flag = print_name_and_link("%-16s ", COLOR_NONE, name, tb);
 
if (tb[IFLA_OPERSTATE])
@@ -868,6 +817,7 @@ int print_linkinfo(const struct sockaddr_nl *who,
int len = n->nlmsg_len;
const char *name;
unsigned int m_flag = 0;
+   SPRINT_BUF(b1);
 
if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK)
return 0;
@@ -916,6 +866,9 @@ int print_linkinfo(const struct sockaddr_nl *who,
if (n->nlmsg_type == RTM_DELLINK)
print_bool(PRINT_ANY, "deleted", "Deleted ", true);
 
+   if (brief)
+   return print_linkinfo_brief(fp, name, ifi, tb);
+
print_int(PRINT_ANY, "ifindex", "%d: ", ifi->ifi_index);
 
m_flag = print_name_and_link("%s: ", COLOR_IFNAME, name, tb);
@@ -948,7 +901,6 @@ int print_linkinfo(const struct sockaddr_nl *who,
print_linkmode(fp, tb[IFLA_LINKMODE]);
 
if (tb[IFLA_GROUP]) {
-   SPRINT_BUF(b1);
int group = rta_getattr_u32(tb[IFLA_GROUP]);
 
print_string(PRINT_ANY,
@@ -964,8 +916,6 @@ int print_linkinfo(const struct sockaddr_nl *who,
print_link_event(fp, rta_getattr_u32(tb[IFLA_EVENT]));
 
if (!filter.family || filter.family == AF_PACKET || show_details) {
-   SPRINT_BUF(b1);
-
print_string(PRINT_FP, NULL, "%s", _SL_);
print_string(PRINT_ANY,
 "link_type",
@@ -1065,7 +1015,6 @@ int print_linkinfo(const struct sockaddr_nl *who,
 

[PATCH iproute2-next v2 6/9] lib: Correct object file dependencies

2018-02-14 Thread Serhey Popovych
Neither internal libnetlink nor libgenl depends on ll_map.o: prepare for
upcoming changes that brings much more cleaner dependency between
utils.o and ll_map.o.

Signed-off-by: Serhey Popovych 
---
 lib/Makefile |4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/Makefile b/lib/Makefile
index 7b34ed5..bab8cbf 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -3,11 +3,11 @@ include ../config.mk
 
 CFLAGS += -fPIC
 
-UTILOBJ = utils.o rt_names.o ll_types.o ll_proto.o ll_addr.o \
+UTILOBJ = utils.o rt_names.o ll_map.o ll_types.o ll_proto.o ll_addr.o \
inet_proto.o namespace.o json_writer.o json_print.o \
names.o color.o bpf.o exec.o fs.o
 
-NLOBJ=libgenl.o ll_map.o libnetlink.o
+NLOBJ=libgenl.o libnetlink.o
 
 all: libnetlink.a libutil.a
 
-- 
1.7.10.4



Re: [PATCH V2 net-next 4/7] rds: support for zcopy completion notification

2018-02-14 Thread Sowmini Varadhan
On (02/14/18 13:10), Santosh Shilimkar wrote:
> >>>RDS support true zero copy already with RDMA transport so some of
> >>>this code can easily get confused.

btw, another way to solve this is to have the RDMA code use the 
suffix "rdma" (which is what it really is) as needed.

--Sowmini




Re: [PATCH] ip_tunnel: Use mark in skb by default

2018-02-14 Thread Thomas Winter
Hello David Miller,

Would this patch be able to be reverted? We have found in further testing that 
this produces undesired results.

For example, using some PBR rule that uses conntrack to set the skb->mark and 
the desired nexthop is a tunnel then the tunnel route selection hits a routing 
loop as the skb->mark is the mark of the encapsulated traffic and route 
selected by init_tunnel_flow is via tunnel itself.

Regards,
Thomas Winter

From: David Miller 
Sent: 25 January 2018 10:31
To: Thomas Winter
Cc: netdev@vger.kernel.org; kuz...@ms2.inr.ac.ru; yoshf...@linux-ipv6.org
Subject: Re: [PATCH] ip_tunnel: Use mark in skb by default

From: Thomas Winter 
Date: Tue, 23 Jan 2018 16:46:24 +1300

> This allows marks set by connmark in iptables
> to be used for route lookups.
>
> Signed-off-by: Thomas Winter 

Applied to net-next, thanks.


Re: [PATCH V6 0/4] Add SELinux SCTP protocol support

2018-02-14 Thread Marcelo Ricardo Leitner
On Wed, Feb 14, 2018 at 02:19:03PM -0500, Paul Moore wrote:
> On Tue, Feb 13, 2018 at 3:52 PM, Richard Haines
>  wrote:
> > These patches have been built on Fedora 27 with kernel-4.16.0-0.rc1 plus
> > the following userspace patches to enable testing:
> >
> > 1) Updates to libsepol 2.7 to support the sctp portcon statement.
> >The patch is available from:
> >  http://arctic.selinuxproject.org/~rhaines/selinux-sctp/
> >  selinux-Add-support-for-the-SCTP-portcon-keyword.patch
> >
> > 2) Updates to the SELinux Test Suite adding SCTP tests. Please read the
> >selinux-testsuite/README.sctp for details. The patch is available from:
> >  http://arctic.selinuxproject.org/~rhaines/selinux-sctp/
> >  selinux-testsuite-Add-SCTP-test-support.patch
> >
> > 3) Updates to lksctp-tools that show SELinux info in sctp_darn and
> >sctp_test. It also contains a minor patch for test_1_to_1_connect.c
> >as when CIPSO/CALIPSO configured, NetLabel returns a different error
> >code for illegal addresses in test 5. The patch is available from:
> >  http://arctic.selinuxproject.org/~rhaines/selinux-sctp/
> >  lksctp-tools-Add-SELinux-support-to-sctp_test-and-sc.patch
> >
> > All SCTP lksctp-tools/src/func_tests run correctly in enforcing mode.
> >
> > All SCTP regression tests "./sctp-tests run" run correctly in enforcing
> > mode. These tests are obtained from: https://github.com/sctp/sctp-tests
> >
> > The selinux-testsuite patch also adds remote tests (that need some manual
> > configuration). These are useful for testing CIPSO/CALIPSO over a network
> > with a number of categories to produce large ip option fields with various
> > message sizes forcing fragmentation etc..
> >
> > Changes since RFC Patch:
> > Removed the NetLabel patch (was [RFC PATCH 4/5] netlabel: Add SCTP support)
> > as re-engineered. However this patchset will require the NetLabel
> > patch at [1] to fully run the SCTP selinux-testsuite.
> >
> > V1 Changes:
> > PATCH 1/4
> > Remove unused parameter from security_sctp_assoc_request().
> > Reformat and update LSM-sctp.rst documentation.
> > PATCH 2/4
> > Add variables and RCU locks as requested in [2] to support IP options.
> > PATCH 3/4
> > Added security_sctp_assoc_request() hook to sctp_sf_do_unexpected_init()
> > and sctp_sf_do_5_2_4_dupcook().
> > Removed security_sctp_assoc_request() hook from sctp_sf_do_5_1C_ack() as
> > no longer required.
> > PATCH 4/4
> > Reformat and update SELinux-sctp.rst documentation.
> > Remove bindx and connectx permissions.
> > Rework selinux_socket_connect() and selinux_netlbl_socket_connect() to
> > utilise helpers for code reuse.
> > Add spinlock to selinux_sctp_assoc_request().
> > Remove unused parameter from security_sctp_assoc_request().
> > Use address->sa_family == AF_INET in *_bind and *_connect to ensure
> > correct address type.
> > Minor cleanups.
> >
> > V2 Changes:
> > PATCH 4/4 - Remove spin lock from selinux_sctp_assoc_request()
> > PATCH 4/4 - Fix selinux_sctp_sk_clone() kbuild test robot catch [3]
> >
> > V3 Changes:
> > PATCH 2/4 - Account for IP options length in sctp.h sctp_frag_point() by
> > Marcelo
> >
> > V4 Changes:
> > PATCH 1/4 - Move specific SELinux descriptions from LSM-sctp.rst and
> > lsm_hooks.h to SELinux-sctp.rst in PATCH 4/4
> > PATCH 4/4 - Rename selinux_netlbl_sctp_socket_connect() to
> > selinux_netlbl_socket_connect_locked() and move description comments to
> > selinux_sctp_bind_connect()
> >
> > V5 Change: Rework selinux_netlbl_socket_connect() and
> > selinux_netlbl_socket_connect_locked as requested by Paul.
> >
> > V6 Changes:
> > Rework SCTP patches 2/4 and 3/4 as there have been major SCTP updates since
> > kernel 4.14.
> >
> > [1] https://marc.info/?l=selinux=151061619115945=2
> > [2] https://marc.info/?l=selinux=150962470215797=2
> > [3] https://marc.info/?l=selinux=151198281817779=2
> >
> > Richard Haines (4):
> >   security: Add support for SCTP security hooks
> >   sctp: Add ip option support
> >   sctp: Add LSM hooks
> >   selinux: Add SCTP support
> 
> Marcelo, or any other SCTP folks, do the SCTP changes still look okay
> to you?  I'd like to merge these into the selinux/next tree by the end
> of the week ...

Other than the issue on patch 2/4, patchset LGTM yes.
(Not really happy with the casts to remove the const attribute on
patch 3, but I don't see other way out)

Thanks,
Marcelo


Re: [PATCH V2 net-next 5/7] rds: zerocopy Tx support.

2018-02-14 Thread Santosh Shilimkar

On 2/14/2018 11:49 AM, Sowmini Varadhan wrote:

On (02/14/18 11:10), Santosh Shilimkar wrote:

s/RDS_CMSG_ZCOPY_COOKIE/RDS_CMSG_ZMSGCOPY_COOKIE



Please see https://www.spinics.net/lists/netdev/msg483627.html


Just saw it and responded to Dave.



@@ -356,6 +358,53 @@ int rds_message_copy_from_user(struct rds_message *rm, 
struct iov_iter *from)
sg = rm->data.op_sg;
sg_off = 0; /* Dear gcc, sg->page will be null from kzalloc. */
+   if (zcopy) {
+   int total_copied = 0;
+   struct sk_buff *skb;
+
+   skb = alloc_skb(SO_EE_ORIGIN_MAX_ZCOOKIES * sizeof(u32),
+   GFP_KERNEL);

This can sleep so you might want to check if you want to use ATOMIC version
here.


I think it should be fine: rds_message_copy_from_user() is called
in process context, and if you notice, the calling function rds_sendmsg()
also has this
1100 rm = rds_message_alloc(ret, GFP_KERNEL);
1101 if (!rm) {
1102 ret = -ENOMEM;
1103 goto out;
1104 }

 :
1106 /* Attach data to the rm */
 :
1113 ret = rds_message_copy_from_user(rm, >msg_iter);

So using GFP_KERNEL is as safe as the call at line 1100.


Was just asking you to check if it is safe. The path already
does that so we are good.




+   return -ENOMEM;
+   }

NOMEM new application visible change but probably the right one for this
particular case. Just need to make sure application can handle this
error.


I think the application already handles this correctly (see line 1102 above)


Indeed. Thanks for checking.

Regards,
Santosh


Re: [PATCH V2 net-next 4/7] rds: support for zcopy completion notification

2018-02-14 Thread Santosh Shilimkar

On 2/14/2018 11:02 AM, David Miller wrote:

From: Sowmini Varadhan 
Date: Wed, 14 Feb 2018 14:01:10 -0500


On (02/14/18 10:50), Santosh Shilimkar wrote:

generic comment and please update it where it is applicable
in terms of variable names, notifiers etc.

RDS support true zero copy already with RDMA transport so some of
this code can easily get confused.

So I suggest something like below.
s/zerocopy/zeromsgcopy
s/zcopy/zmsgcopy
s/zcookie/zmsgcpycookie
s/znotifier/zmsgcpynotifier 


I'd like to hear some additional opinions from the list on this:
the existing socket API for TCP etc.  already uses ZEROCOPY, and other
than extending variable names (and putting me at risk of violating the
"fit within 80 chars per line" requirement, leading to not-so-pretty
line wraps), I'm not seeing much value in this.


I agree, this name change requires seems pointless.  Just keep the names
the way they are, thank you.

Dave I understand your point for generic code and I was not all asking 
to rename anything in generic code.


My point was new code getting added to RDS to support this zero copy
message option. Within RDS, core code is common and all the 
infrastructure with it and it will be hard to follow the code if

that distinction is not maintained.

Ofcourse you have a last say on this list so if you want to
over rule the comment, I will step back :-)

Regards,
Santosh







Re: [net-next 00/12][pull request] 40GbE Intel Wired LAN Driver Updates 2018-02-14

2018-02-14 Thread David Miller
From: Jeff Kirsher 
Date: Wed, 14 Feb 2018 09:45:27 -0800

> This patch series enables the new mqprio hardware offload mechanism
> creating traffic classes on VFs for XL710 devices. The parameters
> needed to configure these traffic classes/queue channels are provides
> by the user via the tc tool. A maximum of four traffic classes can be
> created on each VF. This patch series also enables application of cloud
> filters to each of these traffic classes. The cloud filters are applied
> using the tc-flower classifier.
> 
> Example:
> 1. tc qdisc add dev vf0 root mqprio num_tc 4 map 0 0 0 0 1 2 2 3\
> queues 2@0 2@2 1@4 1@5 hw 1 mode channel
> 2. tc qdisc add dev vf0 ingress
> 3. ethtool -K vf0 hw-tc-offload on
> 4. ip link set eth0 vf 0 spoofchk off
> 5. tc filter add dev vf0 protocol ip parent : prio 1 flower dst_ip\
> 192.168.3.5/32 ip_proto udp dst_port 25 skip_sw hw_tc 2
> 
> The following are changes since commit 
> 1d631583ae5e40681dc9a41d7cfa845222c3c7ff:
>   Merge branch 'net-dev-Make-protocol-ptr-dependent-on-CONFIG'
> and are available in the git repository at:
>   git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-queue 40GbE

Looks great, pulled, thanks Jeff.


Re: [PATCH net-next] kcm: Call strp_stop before strp_done in kcm_attach

2018-02-14 Thread David Miller
From: Tom Herbert 
Date: Wed, 14 Feb 2018 09:22:42 -0800

> In kcm_attach strp_done is called when sk_user_data is already
> set to fail the attach. strp_done needs the strp to be stopped and
> warns if it isn't. Call strp_stop in this case to eliminate the
> warning message.
> 
> Reported-by: syzbot+88dfb55e4c8b770d8...@syzkaller.appspotmail.com
> Fixes: e5571240236c5652f ("kcm: Check if sk_user_data already set in 
> kcm_attach"
> Signed-off-by: Tom Herbert 

Applied, thanks Tom.


Re: [PATCH v3 1/2] net: phy: dp83867: Add binding for the CLK_OUT pin muxing option

2018-02-14 Thread David Miller
From: Daniel Schultz 
Date: Wed, 14 Feb 2018 17:07:11 +0100

> From: Wadim Egorov 
> 
> The DP83867 has a muxing option for the CLK_OUT pin. It is possible
> to set CLK_OUT for different channels.
> Create a binding to select a specific clock for CLK_OUT pin.
> 
> Signed-off-by: Wadim Egorov 
> Signed-off-by: Daniel Schultz 
> ---
> Changes:
>   v2:
> Added check if clk_output_sel has a valid value
> Only write the clock ouput register if a musing is desired
>   v3:
> -

Applied to net-next.


Re: [PATCH v3 2/2] net: phy: dp83867: Add documentation for CLK_OUT pin muxing

2018-02-14 Thread David Miller
From: Daniel Schultz 
Date: Wed, 14 Feb 2018 17:07:12 +0100

> From: Wadim Egorov 
> 
> Add documentation of ti,clk-output-sel which can be used to select
> a specific clock for CLK_OUT.
> 
> Signed-off-by: Wadim Egorov 
> Signed-off-by: Daniel Schultz 
> ---
> Changes:
>   v2:
> -
>   v3:
> Fixed indentation.

Also applied to net-next, thanks.


  1   2   3   >