* Re: [PATCH net-next 1/1] tc-testing: updated police, mirred, skbedit and skbmod with more tests
From: David Miller @ 2018-03-22 18:58 UTC (permalink / raw)
To: mrv; +Cc: stephen, netdev, kernel, jhs, xiyou.wangcong, jiri
In-Reply-To: <1521670670-28439-1-git-send-email-mrv@mojatatu.com>
From: Roman Mashak <mrv@mojatatu.com>
Date: Wed, 21 Mar 2018 18:17:50 -0400
> diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/skbmod.json b/tools/testing/selftests/tc-testing/tc-tests/actions/skbmod.json
> index 90bba48c3f07..8aa5a88ccb19 100644
> --- a/tools/testing/selftests/tc-testing/tc-tests/actions/skbmod.json
> +++ b/tools/testing/selftests/tc-testing/tc-tests/actions/skbmod.json
...
> }
> -]
> +]
> \ No newline at end of file
> --
> 2.7.4
Please fix this.
^ permalink raw reply
* [PATCH net-next,0/2] hv_netvsc: Fix/improve RX path error handling
From: Haiyang Zhang @ 2018-03-22 19:01 UTC (permalink / raw)
To: davem, netdev; +Cc: olaf, sthemmin, haiyangz, linux-kernel, devel, vkuznets
From: Haiyang Zhang <haiyangz@microsoft.com>
Fix the status code returned to the host. Also add range
check for rx packet offset and length.
Haiyang Zhang (2):
hv_netvsc: Fix the return status in RX path
hv_netvsc: Add range checking for rx packet offset and length
drivers/net/hyperv/hyperv_net.h | 1 +
drivers/net/hyperv/netvsc.c | 25 +++++++++++++++++++++----
drivers/net/hyperv/netvsc_drv.c | 2 +-
drivers/net/hyperv/rndis_filter.c | 4 ++--
4 files changed, 25 insertions(+), 7 deletions(-)
--
2.15.1
^ permalink raw reply
* [PATCH net-next,1/2] hv_netvsc: Fix the return status in RX path
From: Haiyang Zhang @ 2018-03-22 19:01 UTC (permalink / raw)
To: davem, netdev; +Cc: olaf, sthemmin, haiyangz, linux-kernel, devel, vkuznets
In-Reply-To: <20180322190114.25596-1-haiyangz@linuxonhyperv.com>
From: Haiyang Zhang <haiyangz@microsoft.com>
As defined in hyperv_net.h, the NVSP_STAT_SUCCESS is one not zero.
Some functions returns 0 when it actually means NVSP_STAT_SUCCESS.
This patch fixes them.
In netvsc_receive(), it puts the last RNDIS packet's receive status
for all packets in a vmxferpage which may contain multiple RNDIS
packets.
This patch puts NVSP_STAT_FAIL in the receive completion if one of
the packets in a vmxferpage fails.
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
drivers/net/hyperv/netvsc.c | 8 ++++++--
drivers/net/hyperv/netvsc_drv.c | 2 +-
drivers/net/hyperv/rndis_filter.c | 4 ++--
3 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index aa95e81af6e5..1ddb2c39b6e4 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -1098,12 +1098,16 @@ static int netvsc_receive(struct net_device *ndev,
void *data = recv_buf
+ vmxferpage_packet->ranges[i].byte_offset;
u32 buflen = vmxferpage_packet->ranges[i].byte_count;
+ int ret;
trace_rndis_recv(ndev, q_idx, data);
/* Pass it to the upper layer */
- status = rndis_filter_receive(ndev, net_device,
- channel, data, buflen);
+ ret = rndis_filter_receive(ndev, net_device,
+ channel, data, buflen);
+
+ if (unlikely(ret != NVSP_STAT_SUCCESS))
+ status = NVSP_STAT_FAIL;
}
enq_receive_complete(ndev, net_device, q_idx,
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index cdb78eefab67..33607995be62 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -818,7 +818,7 @@ int netvsc_recv_callback(struct net_device *net,
u64_stats_update_end(&rx_stats->syncp);
napi_gro_receive(&nvchan->napi, skb);
- return 0;
+ return NVSP_STAT_SUCCESS;
}
static void netvsc_get_drvinfo(struct net_device *net,
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
index 2dc00f714482..591fb8080f11 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -443,10 +443,10 @@ int rndis_filter_receive(struct net_device *ndev,
"unhandled rndis message (type %u len %u)\n",
rndis_msg->ndis_msg_type,
rndis_msg->msg_len);
- break;
+ return NVSP_STAT_FAIL;
}
- return 0;
+ return NVSP_STAT_SUCCESS;
}
static int rndis_filter_query_device(struct rndis_device *dev,
--
2.15.1
^ permalink raw reply related
* [PATCH net-next, 2/2] hv_netvsc: Add range checking for rx packet offset and length
From: Haiyang Zhang @ 2018-03-22 19:01 UTC (permalink / raw)
To: davem, netdev; +Cc: olaf, sthemmin, haiyangz, linux-kernel, devel, vkuznets
In-Reply-To: <20180322190114.25596-1-haiyangz@linuxonhyperv.com>
From: Haiyang Zhang <haiyangz@microsoft.com>
This patch adds range checking for rx packet offset and length.
It may only happen if there is a host side bug.
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
drivers/net/hyperv/hyperv_net.h | 1 +
drivers/net/hyperv/netvsc.c | 17 +++++++++++++++--
2 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 0db3bd1ea06f..49c05ac894e5 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -793,6 +793,7 @@ struct netvsc_device {
/* Receive buffer allocated by us but manages by NetVSP */
void *recv_buf;
+ u32 recv_buf_size; /* allocated bytes */
u32 recv_buf_gpadl_handle;
u32 recv_section_cnt;
u32 recv_section_size;
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 1ddb2c39b6e4..a6700d65f206 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -289,6 +289,8 @@ static int netvsc_init_buf(struct hv_device *device,
goto cleanup;
}
+ net_device->recv_buf_size = buf_size;
+
/*
* Establish the gpadl handle for this buffer on this
* channel. Note: This call uses the vmbus connection rather
@@ -1095,11 +1097,22 @@ static int netvsc_receive(struct net_device *ndev,
/* Each range represents 1 RNDIS pkt that contains 1 ethernet frame */
for (i = 0; i < count; i++) {
- void *data = recv_buf
- + vmxferpage_packet->ranges[i].byte_offset;
+ u32 offset = vmxferpage_packet->ranges[i].byte_offset;
u32 buflen = vmxferpage_packet->ranges[i].byte_count;
+ void *data;
int ret;
+ if (unlikely(offset + buflen > net_device->recv_buf_size)) {
+ status = NVSP_STAT_FAIL;
+ netif_err(net_device_ctx, rx_err, ndev,
+ "Packet offset:%u + len:%u too big\n",
+ offset, buflen);
+
+ continue;
+ }
+
+ data = recv_buf + offset;
+
trace_rndis_recv(ndev, q_idx, data);
/* Pass it to the upper layer */
--
2.15.1
^ permalink raw reply related
* Re: [PATCH V2 net-next] liquidio: Added support for trusted VF
From: David Miller @ 2018-03-22 19:04 UTC (permalink / raw)
To: felix.manlunas
Cc: netdev, raghu.vatsavayi, derek.chickles, satananda.burla,
intiyaz.basha
In-Reply-To: <20180322063054.GA5037@felix-thinkpad.cavium.com>
From: Felix Manlunas <felix.manlunas@cavium.com>
Date: Wed, 21 Mar 2018 23:30:54 -0700
> From: Intiyaz Basha <intiyaz.basha@cavium.com>
>
> When a VF is trusted, all promiscuous traffic will only be sent to that VF.
> In normal operation promiscuous traffic is sent to the PF. There can be
> only one trusted VF per PF
>
> Signed-off-by: Intiyaz Basha <intiyaz.basha@cavium.com>
> Signed-off-by: Felix Manlunas <felix.manlunas@cavium.com>
> ---
> Patch Change Log:
> V1 -> V2:
> Used completion in place of wait queue
Applied, thank you.
^ permalink raw reply
* Re: [PATCH net-next v4 0/5] net: qualcomm: rmnet: Updates 2018-03-12
From: David Miller @ 2018-03-22 19:04 UTC (permalink / raw)
To: subashab; +Cc: joe, netdev
In-Reply-To: <1521683295-22935-1-git-send-email-subashab@codeaurora.org>
From: Subash Abhinov Kasiviswanathan <subashab@codeaurora.org>
Date: Wed, 21 Mar 2018 19:48:10 -0600
> This series contains some minor updates for rmnet driver.
>
> Patch 1 contains fixes for sparse warnings.
> Patch 2 updates the copyright date to 2018.
> Patch 3 is a cleanup in receive path.
> Patch 4 has the new rmnet netlink attributes in uapi and updates the usage.
> Patch 5 has the implementation of the fill_info operation.
>
> v1->v2: Remove the force casts since the data type is changed to __be
> types as mentioned by David.
> v2->v3: Update copyright in files which actually had changes as
> mentioned by Joe.
> v3->v4: Add new netlink attributes for mux_id and flags instead of using the
> the vlan attributes as mentioned by David. The rmnet specific flags are also
> moved to uapi. The netlink updates are done as part of #4 and #5 has the
> fill_info operation.
Series applied, thanks.
^ permalink raw reply
* Re: [RFC PATCH] net: stmmac: dwmac-sun8i: sun8i_syscon_reg_field can be static
From: David Miller @ 2018-03-22 19:07 UTC (permalink / raw)
To: lkp
Cc: mark.rutland, devicetree, maxime.ripard, netdev, mturquette,
sboyd, wens, robh+dt, broonie, kbuild-all, clabbe.montjoie,
peppe.cavallaro, linux-clk, linux-arm-kernel, icenowy
In-Reply-To: <20180322074217.GA7358@ivytown2.lkp.intel.com>
From: kbuild test robot <lkp@intel.com>
Date: Thu, 22 Mar 2018 15:42:18 +0800
>
> Fixes: e3c10deef23c ("net: stmmac: dwmac-sun8i: Use regmap_field for syscon register access")
> Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
This commit ID and this symbol are both not present in any of my trees.
Please avoid using SHA1 IDs which don't actually exist in an upstream
tree. When I see a "Fixes: " tag like this, I expect that it is for a
change in my tree.
^ permalink raw reply
* Re: [patch net-next RFC 00/12] devlink: introduce port flavours and common phys_port_name generation
From: David Ahern @ 2018-03-22 19:10 UTC (permalink / raw)
To: Jiri Pirko
Cc: netdev, davem, idosch, jakub.kicinski, mlxsw, andrew,
vivien.didelot, f.fainelli, michael.chan, ganeshgr, saeedm,
simon.horman, pieter.jansenvanvuuren, john.hurley,
dirk.vandermerwe, alexander.h.duyck, ogerlitz, vijaya.guvva,
satananda.burla, raghu.vatsavayi, felix.manlunas, gospo,
sathya.perla, vasundhara-v.volam, tariqt, eranbe,
jeffrey.t.kirsher
In-Reply-To: <20180322174904.GG2074@nanopsycho.orion>
On 3/22/18 11:49 AM, Jiri Pirko wrote:
> Thu, Mar 22, 2018 at 04:34:07PM CET, dsahern@gmail.com wrote:
>> On 3/22/18 4:55 AM, Jiri Pirko wrote:
>>> From: Jiri Pirko <jiri@mellanox.com>
>>>
>>> This patchset resolves 2 issues we have right now:
>>> 1) There are many netdevices / ports in the system, for port, pf, vf
>>> represenatation but the user has no way to see which is which
>>> 2) The ndo_get_phys_port_name is implemented in each driver separatelly,
>>> which may lead to inconsistent names between drivers.
>>
>> Similar to ndo_get_phys_port_{name,id}, devlink requires drivers to opt
>> in with an implementation right, so you can't really force a solution to
>> the consistent naming.
>
> Yeah, drivers would still have free choice to implemen the ndo
> themselves. But most of them, like all sriov switch drivers should use
> the devlink helper to have consistent naming. In other words, devlink
> helper should be the standard way, in weird cases (like rocker), driver
> implements it himself.
That's an assumption that somehow the devlink API will be better
supported than ndo_get_phys_port_{name,id}. Don't get me wrong -- an API
to show the kind of device is needed, but I do not think this enforces
any kind of consistency in naming.
>
>
>>
>>>
>>> This patchset introduces port flavours which should address the first
>>> problem. I'm testing this with Netronome nfp hardware. When the user
>>> has 2 physical ports, 1 pf, and 4 vfs, he should see something like this:
>>> # devlink port
>>> pci/0000:05:00.0/0: type eth netdev enp5s0np0 flavour physical number 0
>>> pci/0000:05:00.0/268435456: type eth netdev eth0 flavour physical number 0
>>> pci/0000:05:00.0/268435460: type eth netdev enp5s0np1 flavour physical number 1
>>> pci/0000:05:00.0/536875008: type eth netdev eth2 flavour pf_rep number 536875008
>>> pci/0000:05:00.0/536870912: type eth netdev eth1 flavour vf_rep number 0
>>> pci/0000:05:00.0/536870976: type eth netdev eth3 flavour vf_rep number 1
>>> pci/0000:05:00.0/536871040: type eth netdev eth4 flavour vf_rep number 2
>>> pci/0000:05:00.0/536871104: type eth netdev eth5 flavour vf_rep number 3
>>
>> How about 'kind' instead of flavo{u}r?
>
> Yeah, kind is often used in kernel already with different meaning
> git grep kind net/core
> I wanted to avoid confusions
Roopa's amendment works as well; I just think flavor / flavour is the
wrong word. Make me thinks of food ... ice cream vs netdevices.
^ permalink raw reply
* Re: [PATCH net-next v3 0/5] Rework ip_ra_chain protection
From: David Miller @ 2018-03-22 19:14 UTC (permalink / raw)
To: ktkhai
Cc: yoshfuji, edumazet, yanhaishuang, nikolay, yotamg, soheil, avagin,
nicolas.dichtel, ebiederm, fw, roman.kapl, netdev, xiyou.wangcong,
dvyukov, andreyknvl, lkp
In-Reply-To: <152171176936.18202.11912079579606814167.stgit@localhost.localdomain>
From: Kirill Tkhai <ktkhai@virtuozzo.com>
Date: Thu, 22 Mar 2018 12:44:46 +0300
> Commit 1215e51edad1 "ipv4: fix a deadlock in ip_ra_control"
> made rtnl_lock() be used in raw_close(). This function is called
> on every RAW socket destruction, so that rtnl_mutex is taken
> every time. This scales very sadly. I observe cleanup_net()
> spending a lot of time in rtnl_lock() and raw_close() is one
> of the biggest rtnl user (since we have percpu net->ipv4.icmp_sk).
>
> This patchset reworks the locking: reverts the problem commit
> and its descendant, and introduces rtnl-independent locking.
> This may have a continuation, and someone may work on killing
> rtnl_lock() in mrtsock_destruct() in the future.
>
> Thanks,
> Kirill
>
> ---
> v3: Change patches order: [2/5] and [3/5].
> v2: Fix sparse warning [4/5], as reported by kbuild test robot.
This looks a lot better, series applied, thank you.
^ permalink raw reply
* Re: [RESEND PATCH net-next 1/1] tc-testing: updated police, mirred, skbedit and skbmod with more tests
From: David Miller @ 2018-03-22 19:14 UTC (permalink / raw)
To: mrv; +Cc: netdev, jhs, xiyou.wangcong, jiri
In-Reply-To: <1521721402-28750-1-git-send-email-mrv@mojatatu.com>
From: Roman Mashak <mrv@mojatatu.com>
Date: Thu, 22 Mar 2018 08:23:22 -0400
> diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/skbmod.json b/tools/testing/selftests/tc-testing/tc-tests/actions/skbmod.json
> index 90bba48c3f07..8aa5a88ccb19 100644
> --- a/tools/testing/selftests/tc-testing/tc-tests/actions/skbmod.json
> +++ b/tools/testing/selftests/tc-testing/tc-tests/actions/skbmod.json
...
> ]
> }
> -]
> +]
> \ No newline at end of file
> --
> 2.7.4
Please fix this.
^ permalink raw reply
* Re: [PATCH net-next v2] net: mvpp2: Don't use dynamic allocs for local variables
From: Maxime Chevallier @ 2018-03-22 19:14 UTC (permalink / raw)
To: David Miller
Cc: netdev, linux-kernel, antoine.tenart, thomas.petazzoni,
gregory.clement, miquel.raynal, nadavh, stefanc, ymarkman, mw
In-Reply-To: <20180322.144709.550558706036978967.davem@davemloft.net>
Hello David,
On Thu, 22 Mar 2018 14:47:09 -0400 (EDT),
David Miller <davem@davemloft.net> wrote :
> From: Maxime Chevallier <maxime.chevallier@bootlin.com>
> Date: Wed, 21 Mar 2018 16:14:00 +0100
>
> > diff --git a/drivers/net/ethernet/marvell/mvpp2.c
> > b/drivers/net/ethernet/marvell/mvpp2.c index
> > 9bd35f2291d6..28e33e139178 100644 ---
> > a/drivers/net/ethernet/marvell/mvpp2.c +++
> > b/drivers/net/ethernet/marvell/mvpp2.c @@ -1913,16 +1913,11 @@
> > static void mvpp2_prs_sram_offset_set(struct mvpp2_prs_entry *pe, }
> >
> > /* Find parser flow entry */
> > -static struct mvpp2_prs_entry *mvpp2_prs_flow_find(struct mvpp2
> > *priv, int flow) +static int mvpp2_prs_flow_find(struct mvpp2
> > *priv, int flow) {
> > - struct mvpp2_prs_entry *pe;
> > + struct mvpp2_prs_entry pe;
> > int tid;
> >
> > - pe = kzalloc(sizeof(*pe), GFP_KERNEL);
> > - if (!pe)
> > - return NULL;
> > - mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_FLOWS);
> > -
>
> In order to be an equivalent change you must bzero out this 'pe'
> object on the stack. You are only initializing the index member
> before passing it into other functions.
I agree that this is unclear, but the functions I pass these objects to
only need the index field to be set, and will fill the rest of the
object according to the underlying HW representation (these objects
mirror the HW configuration).
I can see that this is confusing, we might want to make the
mvpp2_prs_hw_read function more explicit about this.
Would comments explaning this be enough, or should I try another way to
make this cleaner ?
Thanks,
Maxime
^ permalink raw reply
* Re: [PATCH net-next 1/1] tc-testing: Correct compound statements for namespace execution
From: Lucas Bates @ 2018-03-22 19:14 UTC (permalink / raw)
To: David Miller
Cc: Linux Kernel Network Developers, kernel, Jamal Hadi Salim,
Cong Wang, Jiri Pirko
In-Reply-To: <20180322.144805.414248356089707277.davem@davemloft.net>
On Thu, Mar 22, 2018 at 2:48 PM, David Miller <davem@davemloft.net> wrote:
> From: Lucas Bates <lucasb@mojatatu.com>
> Date: Wed, 21 Mar 2018 11:49:40 -0400
>
>> }
>> -]
>> \ No newline at end of file
>> +]
>> --
>> 2.7.4
>
> Please fix this.
This patch fixes the gact.json file that had no newline on the end.
^ permalink raw reply
* Re: [PATCH] caif_dev: use true and false for boolean values
From: Gustavo A. R. Silva @ 2018-03-22 19:24 UTC (permalink / raw)
To: Dmitry Tarnyagin, David S. Miller; +Cc: netdev, linux-kernel
In-Reply-To: <20180305220537.GA15924@embeddedor.com>
Hi all,
I was just wondering about the status of this patch.
Thanks!
--
Gustavo
On 03/05/2018 04:05 PM, Gustavo A. R. Silva wrote:
> Assign true or false to boolean variables instead of an integer value.
>
> This issue was detected with the help of Coccinelle.
>
> Signed-off-by: Gustavo A. R. Silva <garsilva@embeddedor.com>
> ---
> net/caif/caif_dev.c | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c
> index e0adcd1..f2848d6 100644
> --- a/net/caif/caif_dev.c
> +++ b/net/caif/caif_dev.c
> @@ -139,7 +139,7 @@ static void caif_flow_cb(struct sk_buff *skb)
>
> spin_lock_bh(&caifd->flow_lock);
> send_xoff = caifd->xoff;
> - caifd->xoff = 0;
> + caifd->xoff = false;
> dtor = caifd->xoff_skb_dtor;
>
> if (WARN_ON(caifd->xoff_skb != skb))
> @@ -213,7 +213,7 @@ static int transmit(struct cflayer *layer, struct cfpkt *pkt)
> pr_debug("queue has stopped(%d) or is full (%d > %d)\n",
> netif_queue_stopped(caifd->netdev),
> qlen, high);
> - caifd->xoff = 1;
> + caifd->xoff = true;
> caifd->xoff_skb = skb;
> caifd->xoff_skb_dtor = skb->destructor;
> skb->destructor = caif_flow_cb;
> @@ -400,7 +400,7 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what,
> break;
> }
>
> - caifd->xoff = 0;
> + caifd->xoff = false;
> cfcnfg_set_phy_state(cfg, &caifd->layer, true);
> rcu_read_unlock();
>
> @@ -435,7 +435,7 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what,
> if (caifd->xoff_skb_dtor != NULL && caifd->xoff_skb != NULL)
> caifd->xoff_skb->destructor = caifd->xoff_skb_dtor;
>
> - caifd->xoff = 0;
> + caifd->xoff = false;
> caifd->xoff_skb_dtor = NULL;
> caifd->xoff_skb = NULL;
>
>
^ permalink raw reply
* Re: [patch net-next RFC 00/12] devlink: introduce port flavours and common phys_port_name generation
From: Andy Gospodarek @ 2018-03-22 19:25 UTC (permalink / raw)
To: David Ahern
Cc: Jiri Pirko, netdev, davem, idosch, jakub.kicinski, mlxsw, andrew,
vivien.didelot, f.fainelli, michael.chan, ganeshgr, saeedm,
simon.horman, pieter.jansenvanvuuren, john.hurley,
dirk.vandermerwe, alexander.h.duyck, ogerlitz, vijaya.guvva,
satananda.burla, raghu.vatsavayi, felix.manlunas, sathya.perla,
vasundhara-v.volam, tariqt, eranbe, jeffrey.t.kirsher
In-Reply-To: <fde6feca-9616-c3a9-2ab5-1ecfe8741ca6@gmail.com>
On Thu, Mar 22, 2018 at 01:10:38PM -0600, David Ahern wrote:
> On 3/22/18 11:49 AM, Jiri Pirko wrote:
> > Thu, Mar 22, 2018 at 04:34:07PM CET, dsahern@gmail.com wrote:
> >> On 3/22/18 4:55 AM, Jiri Pirko wrote:
> >>> From: Jiri Pirko <jiri@mellanox.com>
> >>>
> >>> This patchset resolves 2 issues we have right now:
> >>> 1) There are many netdevices / ports in the system, for port, pf, vf
> >>> represenatation but the user has no way to see which is which
> >>> 2) The ndo_get_phys_port_name is implemented in each driver separatelly,
> >>> which may lead to inconsistent names between drivers.
> >>
> >> Similar to ndo_get_phys_port_{name,id}, devlink requires drivers to opt
> >> in with an implementation right, so you can't really force a solution to
> >> the consistent naming.
> >
> > Yeah, drivers would still have free choice to implemen the ndo
> > themselves. But most of them, like all sriov switch drivers should use
> > the devlink helper to have consistent naming. In other words, devlink
> > helper should be the standard way, in weird cases (like rocker), driver
> > implements it himself.
>
> That's an assumption that somehow the devlink API will be better
> supported than ndo_get_phys_port_{name,id}. Don't get me wrong -- an API
> to show the kind of device is needed, but I do not think this enforces
> any kind of consistency in naming.
>
> >
> >
> >>
> >>>
> >>> This patchset introduces port flavours which should address the first
> >>> problem. I'm testing this with Netronome nfp hardware. When the user
> >>> has 2 physical ports, 1 pf, and 4 vfs, he should see something like this:
> >>> # devlink port
> >>> pci/0000:05:00.0/0: type eth netdev enp5s0np0 flavour physical number 0
> >>> pci/0000:05:00.0/268435456: type eth netdev eth0 flavour physical number 0
> >>> pci/0000:05:00.0/268435460: type eth netdev enp5s0np1 flavour physical number 1
> >>> pci/0000:05:00.0/536875008: type eth netdev eth2 flavour pf_rep number 536875008
> >>> pci/0000:05:00.0/536870912: type eth netdev eth1 flavour vf_rep number 0
> >>> pci/0000:05:00.0/536870976: type eth netdev eth3 flavour vf_rep number 1
> >>> pci/0000:05:00.0/536871040: type eth netdev eth4 flavour vf_rep number 2
> >>> pci/0000:05:00.0/536871104: type eth netdev eth5 flavour vf_rep number 3
> >>
> >> How about 'kind' instead of flavo{u}r?
> >
> > Yeah, kind is often used in kernel already with different meaning
> > git grep kind net/core
> > I wanted to avoid confusions
>
> Roopa's amendment works as well; I just think flavor / flavour is the
> wrong word. Make me thinks of food ... ice cream vs netdevices.
Naming it a 'subtype' could also work. It's a bit longer than 'kind'
(no longer than 'flavour') and accurately describes the characteristic
of this port. It also avoids the namespace collision of 'kind' that
Jiri points out.
It also fits with the names used in the PCI world with vendor:device and
subsystem vendor:subsystem device naming used there for further
granularity.
^ permalink raw reply
* Re: [RESEND PATCH net-next 1/1] tc-testing: updated police, mirred, skbedit and skbmod with more tests
From: Roman Mashak @ 2018-03-22 19:29 UTC (permalink / raw)
To: David Miller; +Cc: netdev, jhs, xiyou.wangcong, jiri
In-Reply-To: <20180322.151449.503087758560703302.davem@davemloft.net>
David Miller <davem@davemloft.net> writes:
> From: Roman Mashak <mrv@mojatatu.com>
> Date: Thu, 22 Mar 2018 08:23:22 -0400
>
>> diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/skbmod.json b/tools/testing/selftests/tc-testing/tc-tests/actions/skbmod.json
>> index 90bba48c3f07..8aa5a88ccb19 100644
>> --- a/tools/testing/selftests/tc-testing/tc-tests/actions/skbmod.json
>> +++ b/tools/testing/selftests/tc-testing/tc-tests/actions/skbmod.json
> ...
>> ]
>> }
>> -]
>> +]
>> \ No newline at end of file
>> --
>> 2.7.4
>
> Please fix this.
The patch updates police.json, mirred.json, skbedit.json and
skbmod.json files that initially had no newline on the end.
^ permalink raw reply
* Re: [PATCH v3 bpf-next 01/10] treewide: remove struct-pass-by-value from tracepoints arguments
From: Alexei Starovoitov @ 2018-03-22 19:31 UTC (permalink / raw)
To: Steven Rostedt
Cc: davem, daniel, torvalds, peterz, netdev, kernel-team, linux-api
In-Reply-To: <20180322141119.7c876c13@gandalf.local.home>
On 3/22/18 11:11 AM, Steven Rostedt wrote:
> On Thu, 22 Mar 2018 11:01:48 -0700
> Alexei Starovoitov <ast@fb.com> wrote:
>
>> From: Alexei Starovoitov <ast@kernel.org>
>>
>> Fix all tracepoint arguments to pass structures (large and small) by reference
>> instead of by value.
>> Avoiding passing large structs by value is a good coding style.
>> Passing small structs sometimes is beneficial, but in all cases
>> it makes no difference vs readability of the code.
>> The subsequent patch enforces that all tracepoints args are either integers
>> or pointers and fit into 64-bit.
>
> But some of these structures are used to force type checking, and are
> just the same size as a number. That's why they don't have "struct" in
> front of them. Like pmd_t. Will the subsequent patches really break if
> the structure itself has one element that is of size long? Just seems
> to add extra code to pass in an address to something that fits into a
> single register.
yeah. C doesn't allow casting of 'struct s { u64 var };' into u64
without massive hacks and aliasing warnings by compiler.
CAST_TO_U64 macro in patch 7 will prevent tracepoint arguments to be
things like pmd_t. It's not perfect, but doing & of pmd_t variable
is imo clean enough as you can see in this patch.
The macro can be tweaked to do the cast like
*(sizeof(typeof(arg))*)&arg,
but there is no way to get rid of compiler warning.
^ permalink raw reply
* Re: [PATCH net-next 0/9] Add support of VF Reset to HNS3 VF driver
From: David Miller @ 2018-03-22 19:34 UTC (permalink / raw)
To: salil.mehta; +Cc: yisen.zhuang, mehta.salil.lnk, netdev, linux-kernel, linuxarm
In-Reply-To: <20180322142900.22860-1-salil.mehta@huawei.com>
From: Salil Mehta <salil.mehta@huawei.com>
Date: Thu, 22 Mar 2018 14:28:51 +0000
> This patch-set adds the support of VF reset to the existing VF driver.
> VF Reset can be triggered due to TX watchdog firing as a result of TX
> data-path not working. VF reset could also be a result of some internal
> configuration changes if that requires reset, or as a result of the
> PF/Core/Global/IMP(Integrated Management Processor) reset happened in
> the PF.
>
> Summary of Patches:
> * Watchdog timer trigger chnages are present in Patch 1.
> * Reset Service Task and related Event handling is present in Patches {2,3}
> * Changes to send reset request to PF, reset stack and re-initialization
> of the hclge device is present in Patches {4,5,6}
> * Changes related to ARQ (Asynchronous Receive Queue) and its event handling
> are present in Patches {7,8}
> * Changes required in PF to handle the VF Reset request and actually perform
> hardware VF reset is there in Patch 9.
>
>
> NOTE: This patch depends upon "[PATCH net-next 00/11] fix some bugs for HNS3 driver"
> Link: https://lkml.org/lkml/2018/3/21/72
Series applied, thank you.
Please audit your usage of the various reset state bits.
In most places you do the correct atomic sequence by making use of
test_and_set_bit() and test_and_clear_bit().
But in some cases you do things like:
if (!test_bit(X) && !test_bit(Y)) {
...
set_bit(Y);
}
which is racy.
^ permalink raw reply
* [net-next 0/8] tipc: introduce 128-bit auto-configurable node id
From: Jon Maloy @ 2018-03-22 19:42 UTC (permalink / raw)
To: davem, netdev; +Cc: tipc-discussion, mohan.krishna.ghanta.krishnamurthy
We introduce a 128-bit free-format node identity as an alternative to
the legacy <Zone.Cluster.Node> structured 32-bit node address.
We also make configuration of this identity optional; if a bearer is
enabled without a pre-configured node id it will be set automatically
based on the used interface's MAC or IP address.
Jon Maloy (8):
tipc: refactor function tipc_enable_bearer()
tipc: some cleanups in the file discover.c
tipc: remove restrictions on node address values
tipc: allow closest-first lookup algorithm when legacy address is
configured
tipc: remove direct accesses to own_addr field in struct tipc_net
tipc: add 128-bit node identifier
tipc: handle collisions of 32-bit node address hash values
tipc: obtain node identity from interface by default
include/uapi/linux/tipc_netlink.h | 2 +
net/tipc/addr.c | 128 +++++++------
net/tipc/addr.h | 37 ++--
net/tipc/bearer.c | 152 +++++++--------
net/tipc/bearer.h | 2 +-
net/tipc/core.c | 6 +-
net/tipc/core.h | 11 +-
net/tipc/discover.c | 392 ++++++++++++++++++++++----------------
net/tipc/discover.h | 8 +-
net/tipc/link.c | 33 ++--
net/tipc/link.h | 4 +-
net/tipc/msg.h | 23 ++-
net/tipc/name_distr.c | 17 +-
net/tipc/name_table.c | 14 +-
net/tipc/net.c | 80 ++++----
net/tipc/net.h | 5 +-
net/tipc/node.c | 101 ++++++++--
net/tipc/node.h | 8 +-
net/tipc/socket.c | 23 +--
net/tipc/udp_media.c | 13 ++
20 files changed, 634 insertions(+), 425 deletions(-)
--
2.1.4
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
^ permalink raw reply
* [net-next 1/8] tipc: refactor function tipc_enable_bearer()
From: Jon Maloy @ 2018-03-22 19:42 UTC (permalink / raw)
To: davem, netdev; +Cc: tipc-discussion, mohan.krishna.ghanta.krishnamurthy
In-Reply-To: <1521747772-7727-1-git-send-email-jon.maloy@ericsson.com>
As a preparation for the next commits we try to reduce the footprint of
the function tipc_enable_bearer(), while hopefully making is simpler to
follow.
Acked-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
---
net/tipc/bearer.c | 136 ++++++++++++++++++++++++++++--------------------------
1 file changed, 70 insertions(+), 66 deletions(-)
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index f3d2e83..e18cb27 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -230,88 +230,90 @@ void tipc_bearer_remove_dest(struct net *net, u32 bearer_id, u32 dest)
* tipc_enable_bearer - enable bearer with the given name
*/
static int tipc_enable_bearer(struct net *net, const char *name,
- u32 disc_domain, u32 priority,
+ u32 disc_domain, u32 prio,
struct nlattr *attr[])
{
- struct tipc_net *tn = net_generic(net, tipc_net_id);
+ struct tipc_net *tn = tipc_net(net);
+ struct tipc_bearer_names b_names;
+ u32 self = tipc_own_addr(net);
+ int with_this_prio = 1;
struct tipc_bearer *b;
struct tipc_media *m;
- struct tipc_bearer_names b_names;
struct sk_buff *skb;
char addr_string[16];
- u32 bearer_id;
- u32 with_this_prio;
- u32 i;
+ int bearer_id = 0;
int res = -EINVAL;
+ char *errstr = "";
- if (!tn->own_addr) {
- pr_warn("Bearer <%s> rejected, not supported in standalone mode\n",
- name);
- return -ENOPROTOOPT;
+ if (!self) {
+ errstr = "not supported in standalone mode";
+ res = -ENOPROTOOPT;
+ goto rejected;
}
+
if (!bearer_name_validate(name, &b_names)) {
- pr_warn("Bearer <%s> rejected, illegal name\n", name);
- return -EINVAL;
+ errstr = "illegal name";
+ goto rejected;
}
- if (tipc_addr_domain_valid(disc_domain) &&
- (disc_domain != tn->own_addr)) {
- if (tipc_in_scope(disc_domain, tn->own_addr)) {
- disc_domain = tn->own_addr & TIPC_ZONE_CLUSTER_MASK;
- res = 0; /* accept any node in own cluster */
- } else if (in_own_cluster_exact(net, disc_domain))
- res = 0; /* accept specified node in own cluster */
+
+ if (tipc_addr_domain_valid(disc_domain) && disc_domain != self) {
+ if (tipc_in_scope(disc_domain, self)) {
+ /* Accept any node in own cluster */
+ disc_domain = self & TIPC_ZONE_CLUSTER_MASK;
+ res = 0;
+ } else if (in_own_cluster_exact(net, disc_domain)) {
+ /* Accept specified node in own cluster */
+ res = 0;
+ }
}
if (res) {
- pr_warn("Bearer <%s> rejected, illegal discovery domain\n",
- name);
- return -EINVAL;
+ errstr = "illegal discovery domain";
+ goto rejected;
}
- if ((priority > TIPC_MAX_LINK_PRI) &&
- (priority != TIPC_MEDIA_LINK_PRI)) {
- pr_warn("Bearer <%s> rejected, illegal priority\n", name);
- return -EINVAL;
+
+ if (prio > TIPC_MAX_LINK_PRI && prio != TIPC_MEDIA_LINK_PRI) {
+ errstr = "illegal priority";
+ goto rejected;
}
m = tipc_media_find(b_names.media_name);
if (!m) {
- pr_warn("Bearer <%s> rejected, media <%s> not registered\n",
- name, b_names.media_name);
- return -EINVAL;
+ errstr = "media not registered";
+ goto rejected;
}
- if (priority == TIPC_MEDIA_LINK_PRI)
- priority = m->priority;
+ if (prio == TIPC_MEDIA_LINK_PRI)
+ prio = m->priority;
-restart:
- bearer_id = MAX_BEARERS;
- with_this_prio = 1;
- for (i = MAX_BEARERS; i-- != 0; ) {
- b = rtnl_dereference(tn->bearer_list[i]);
- if (!b) {
- bearer_id = i;
- continue;
- }
+ /* Check new bearer vs existing ones and find free bearer id if any */
+ while (bearer_id < MAX_BEARERS) {
+ b = rtnl_dereference(tn->bearer_list[bearer_id]);
+ if (!b)
+ break;
if (!strcmp(name, b->name)) {
- pr_warn("Bearer <%s> rejected, already enabled\n",
- name);
- return -EINVAL;
+ errstr = "already enabled";
+ goto rejected;
}
- if ((b->priority == priority) &&
- (++with_this_prio > 2)) {
- if (priority-- == 0) {
- pr_warn("Bearer <%s> rejected, duplicate priority\n",
- name);
- return -EINVAL;
- }
- pr_warn("Bearer <%s> priority adjustment required %u->%u\n",
- name, priority + 1, priority);
- goto restart;
+ bearer_id++;
+ if (b->priority != prio)
+ continue;
+ if (++with_this_prio <= 2)
+ continue;
+ pr_warn("Bearer <%s>: already 2 bearers with priority %u\n",
+ name, prio);
+ if (prio == TIPC_MIN_LINK_PRI) {
+ errstr = "cannot adjust to lower";
+ goto rejected;
}
+ pr_warn("Bearer <%s>: trying with adjusted priority\n", name);
+ prio--;
+ bearer_id = 0;
+ with_this_prio = 1;
}
+
if (bearer_id >= MAX_BEARERS) {
- pr_warn("Bearer <%s> rejected, bearer limit reached (%u)\n",
- name, MAX_BEARERS);
- return -EINVAL;
+ errstr = "max 3 bearers permitted";
+ goto rejected;
}
b = kzalloc(sizeof(*b), GFP_ATOMIC);
@@ -322,10 +324,9 @@ static int tipc_enable_bearer(struct net *net, const char *name,
b->media = m;
res = m->enable_media(net, b, attr);
if (res) {
- pr_warn("Bearer <%s> rejected, enable failure (%d)\n",
- name, -res);
kfree(b);
- return -EINVAL;
+ errstr = "failed to enable media";
+ goto rejected;
}
b->identity = bearer_id;
@@ -333,15 +334,15 @@ static int tipc_enable_bearer(struct net *net, const char *name,
b->window = m->window;
b->domain = disc_domain;
b->net_plane = bearer_id + 'A';
- b->priority = priority;
+ b->priority = prio;
test_and_set_bit_lock(0, &b->up);
res = tipc_disc_create(net, b, &b->bcast_addr, &skb);
if (res) {
bearer_disable(net, b);
- pr_warn("Bearer <%s> rejected, discovery object creation failed\n",
- name);
- return -EINVAL;
+ kfree(b);
+ errstr = "failed to create discoverer";
+ goto rejected;
}
rcu_assign_pointer(tn->bearer_list[bearer_id], b);
@@ -353,9 +354,12 @@ static int tipc_enable_bearer(struct net *net, const char *name,
return -ENOMEM;
}
- pr_info("Enabled bearer <%s>, discovery domain %s, priority %u\n",
- name,
- tipc_addr_string_fill(addr_string, disc_domain), priority);
+ tipc_addr_string_fill(addr_string, disc_domain);
+ pr_info("Enabled bearer <%s>, discovery scope %s, priority %u\n",
+ name, addr_string, prio);
+ return res;
+rejected:
+ pr_warn("Bearer <%s> rejected, %s\n", name, errstr);
return res;
}
--
2.1.4
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
^ permalink raw reply related
* [net-next 2/8] tipc: some cleanups in the file discover.c
From: Jon Maloy @ 2018-03-22 19:42 UTC (permalink / raw)
To: davem, netdev; +Cc: tipc-discussion, mohan.krishna.ghanta.krishnamurthy
In-Reply-To: <1521747772-7727-1-git-send-email-jon.maloy@ericsson.com>
To facilitate the coming changes in the neighbor discovery functionality
we make some renaming and refactoring of that code. The functional changes
in this commit are trivial, e.g., that we move the message sending call in
tipc_disc_timeout() outside the spinlock protected region.
Acked-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
---
net/tipc/bearer.c | 8 +-
net/tipc/bearer.h | 2 +-
net/tipc/discover.c | 303 +++++++++++++++++++++++++---------------------------
net/tipc/discover.h | 8 +-
4 files changed, 155 insertions(+), 166 deletions(-)
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index e18cb27..76340b9 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -210,7 +210,7 @@ void tipc_bearer_add_dest(struct net *net, u32 bearer_id, u32 dest)
rcu_read_lock();
b = rcu_dereference_rtnl(tn->bearer_list[bearer_id]);
if (b)
- tipc_disc_add_dest(b->link_req);
+ tipc_disc_add_dest(b->disc);
rcu_read_unlock();
}
@@ -222,7 +222,7 @@ void tipc_bearer_remove_dest(struct net *net, u32 bearer_id, u32 dest)
rcu_read_lock();
b = rcu_dereference_rtnl(tn->bearer_list[bearer_id]);
if (b)
- tipc_disc_remove_dest(b->link_req);
+ tipc_disc_remove_dest(b->disc);
rcu_read_unlock();
}
@@ -389,8 +389,8 @@ static void bearer_disable(struct net *net, struct tipc_bearer *b)
tipc_node_delete_links(net, bearer_id);
b->media->disable_media(b);
RCU_INIT_POINTER(b->media_ptr, NULL);
- if (b->link_req)
- tipc_disc_delete(b->link_req);
+ if (b->disc)
+ tipc_disc_delete(b->disc);
RCU_INIT_POINTER(tn->bearer_list[bearer_id], NULL);
kfree_rcu(b, rcu);
tipc_mon_delete(net, bearer_id);
diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h
index a53613d..6efcee6 100644
--- a/net/tipc/bearer.h
+++ b/net/tipc/bearer.h
@@ -159,7 +159,7 @@ struct tipc_bearer {
u32 tolerance;
u32 domain;
u32 identity;
- struct tipc_link_req *link_req;
+ struct tipc_discoverer *disc;
char net_plane;
unsigned long up;
};
diff --git a/net/tipc/discover.c b/net/tipc/discover.c
index 92e4828..09f7555 100644
--- a/net/tipc/discover.c
+++ b/net/tipc/discover.c
@@ -39,34 +39,34 @@
#include "discover.h"
/* min delay during bearer start up */
-#define TIPC_LINK_REQ_INIT msecs_to_jiffies(125)
+#define TIPC_DISC_INIT msecs_to_jiffies(125)
/* max delay if bearer has no links */
-#define TIPC_LINK_REQ_FAST msecs_to_jiffies(1000)
+#define TIPC_DISC_FAST msecs_to_jiffies(1000)
/* max delay if bearer has links */
-#define TIPC_LINK_REQ_SLOW msecs_to_jiffies(60000)
+#define TIPC_DISC_SLOW msecs_to_jiffies(60000)
/* indicates no timer in use */
-#define TIPC_LINK_REQ_INACTIVE 0xffffffff
+#define TIPC_DISC_INACTIVE 0xffffffff
/**
- * struct tipc_link_req - information about an ongoing link setup request
+ * struct tipc_discoverer - information about an ongoing link setup request
* @bearer_id: identity of bearer issuing requests
* @net: network namespace instance
* @dest: destination address for request messages
* @domain: network domain to which links can be established
* @num_nodes: number of nodes currently discovered (i.e. with an active link)
* @lock: spinlock for controlling access to requests
- * @buf: request message to be (repeatedly) sent
+ * @skb: request message to be (repeatedly) sent
* @timer: timer governing period between requests
* @timer_intv: current interval between requests (in ms)
*/
-struct tipc_link_req {
+struct tipc_discoverer {
u32 bearer_id;
struct tipc_media_addr dest;
struct net *net;
u32 domain;
int num_nodes;
spinlock_t lock;
- struct sk_buff *buf;
+ struct sk_buff *skb;
struct timer_list timer;
unsigned long timer_intv;
};
@@ -77,22 +77,35 @@ struct tipc_link_req {
* @type: message type (request or response)
* @b: ptr to bearer issuing message
*/
-static void tipc_disc_init_msg(struct net *net, struct sk_buff *buf, u32 type,
- struct tipc_bearer *b)
+static void tipc_disc_init_msg(struct net *net, struct sk_buff *skb,
+ u32 mtyp, struct tipc_bearer *b)
{
- struct tipc_net *tn = net_generic(net, tipc_net_id);
- struct tipc_msg *msg;
+ struct tipc_net *tn = tipc_net(net);
u32 dest_domain = b->domain;
+ struct tipc_msg *hdr;
- msg = buf_msg(buf);
- tipc_msg_init(tn->own_addr, msg, LINK_CONFIG, type,
+ hdr = buf_msg(skb);
+ tipc_msg_init(tn->own_addr, hdr, LINK_CONFIG, mtyp,
MAX_H_SIZE, dest_domain);
- msg_set_non_seq(msg, 1);
- msg_set_node_sig(msg, tn->random);
- msg_set_node_capabilities(msg, TIPC_NODE_CAPABILITIES);
- msg_set_dest_domain(msg, dest_domain);
- msg_set_bc_netid(msg, tn->net_id);
- b->media->addr2msg(msg_media_addr(msg), &b->addr);
+ msg_set_non_seq(hdr, 1);
+ msg_set_node_sig(hdr, tn->random);
+ msg_set_node_capabilities(hdr, TIPC_NODE_CAPABILITIES);
+ msg_set_dest_domain(hdr, dest_domain);
+ msg_set_bc_netid(hdr, tn->net_id);
+ b->media->addr2msg(msg_media_addr(hdr), &b->addr);
+}
+
+static void tipc_disc_msg_xmit(struct net *net, u32 mtyp, u32 dst, u32 src,
+ struct tipc_media_addr *maddr,
+ struct tipc_bearer *b)
+{
+ struct sk_buff *skb;
+
+ skb = tipc_buf_acquire(MAX_H_SIZE, GFP_ATOMIC);
+ if (!skb)
+ return;
+ tipc_disc_init_msg(net, skb, mtyp, b);
+ tipc_bearer_xmit_skb(net, b->identity, skb, maddr);
}
/**
@@ -116,149 +129,123 @@ static void disc_dupl_alert(struct tipc_bearer *b, u32 node_addr,
/**
* tipc_disc_rcv - handle incoming discovery message (request or response)
- * @net: the applicable net namespace
- * @buf: buffer containing message
- * @bearer: bearer that message arrived on
+ * @net: applicable net namespace
+ * @skb: buffer containing message
+ * @b: bearer that message arrived on
*/
void tipc_disc_rcv(struct net *net, struct sk_buff *skb,
- struct tipc_bearer *bearer)
+ struct tipc_bearer *b)
{
- struct tipc_net *tn = net_generic(net, tipc_net_id);
- struct tipc_media_addr maddr;
- struct sk_buff *rskb;
+ struct tipc_net *tn = tipc_net(net);
struct tipc_msg *hdr = buf_msg(skb);
- u32 ddom = msg_dest_domain(hdr);
- u32 onode = msg_prevnode(hdr);
+ u16 caps = msg_node_capabilities(hdr);
+ u32 signature = msg_node_sig(hdr);
+ u32 dst = msg_dest_domain(hdr);
u32 net_id = msg_bc_netid(hdr);
+ u32 self = tipc_own_addr(net);
+ struct tipc_media_addr maddr;
+ u32 src = msg_prevnode(hdr);
u32 mtyp = msg_type(hdr);
- u32 signature = msg_node_sig(hdr);
- u16 caps = msg_node_capabilities(hdr);
- bool respond = false;
bool dupl_addr = false;
+ bool respond = false;
int err;
- err = bearer->media->msg2addr(bearer, &maddr, msg_media_addr(hdr));
+ err = b->media->msg2addr(b, &maddr, msg_media_addr(hdr));
kfree_skb(skb);
- if (err)
+ if (err || maddr.broadcast) {
+ pr_warn_ratelimited("Rcv corrupt discovery message\n");
return;
-
- /* Ensure message from node is valid and communication is permitted */
- if (net_id != tn->net_id)
+ }
+ /* Ignore discovery messages from own node */
+ if (!memcmp(&maddr, &b->addr, sizeof(maddr)))
return;
- if (maddr.broadcast)
+ if (net_id != tn->net_id)
return;
- if (!tipc_addr_domain_valid(ddom))
+ if (!tipc_addr_domain_valid(dst))
return;
- if (!tipc_addr_node_valid(onode))
+ if (!tipc_addr_node_valid(src))
return;
-
- if (in_own_node(net, onode)) {
- if (memcmp(&maddr, &bearer->addr, sizeof(maddr)))
- disc_dupl_alert(bearer, tn->own_addr, &maddr);
+ if (in_own_node(net, src)) {
+ disc_dupl_alert(b, self, &maddr);
return;
}
- if (!tipc_in_scope(ddom, tn->own_addr))
+ if (!tipc_in_scope(dst, self))
return;
- if (!tipc_in_scope(bearer->domain, onode))
+ if (!tipc_in_scope(b->domain, src))
return;
-
- tipc_node_check_dest(net, onode, bearer, caps, signature,
+ tipc_node_check_dest(net, src, b, caps, signature,
&maddr, &respond, &dupl_addr);
if (dupl_addr)
- disc_dupl_alert(bearer, onode, &maddr);
-
- /* Send response, if necessary */
- if (respond && (mtyp == DSC_REQ_MSG)) {
- rskb = tipc_buf_acquire(MAX_H_SIZE, GFP_ATOMIC);
- if (!rskb)
- return;
- tipc_disc_init_msg(net, rskb, DSC_RESP_MSG, bearer);
- tipc_bearer_xmit_skb(net, bearer->identity, rskb, &maddr);
- }
+ disc_dupl_alert(b, src, &maddr);
+ if (!respond)
+ return;
+ if (mtyp != DSC_REQ_MSG)
+ return;
+ tipc_disc_msg_xmit(net, DSC_RESP_MSG, src, self, &maddr, b);
}
-/**
- * disc_update - update frequency of periodic link setup requests
- * @req: ptr to link request structure
- *
- * Reinitiates discovery process if discovery object has no associated nodes
- * and is either not currently searching or is searching at a slow rate
+/* tipc_disc_add_dest - increment set of discovered nodes
*/
-static void disc_update(struct tipc_link_req *req)
+void tipc_disc_add_dest(struct tipc_discoverer *d)
{
- if (!req->num_nodes) {
- if ((req->timer_intv == TIPC_LINK_REQ_INACTIVE) ||
- (req->timer_intv > TIPC_LINK_REQ_FAST)) {
- req->timer_intv = TIPC_LINK_REQ_INIT;
- mod_timer(&req->timer, jiffies + req->timer_intv);
- }
- }
+ spin_lock_bh(&d->lock);
+ d->num_nodes++;
+ spin_unlock_bh(&d->lock);
}
-/**
- * tipc_disc_add_dest - increment set of discovered nodes
- * @req: ptr to link request structure
+/* tipc_disc_remove_dest - decrement set of discovered nodes
*/
-void tipc_disc_add_dest(struct tipc_link_req *req)
+void tipc_disc_remove_dest(struct tipc_discoverer *d)
{
- spin_lock_bh(&req->lock);
- req->num_nodes++;
- spin_unlock_bh(&req->lock);
-}
+ int intv, num;
-/**
- * tipc_disc_remove_dest - decrement set of discovered nodes
- * @req: ptr to link request structure
- */
-void tipc_disc_remove_dest(struct tipc_link_req *req)
-{
- spin_lock_bh(&req->lock);
- req->num_nodes--;
- disc_update(req);
- spin_unlock_bh(&req->lock);
+ spin_lock_bh(&d->lock);
+ d->num_nodes--;
+ num = d->num_nodes;
+ intv = d->timer_intv;
+ if (!num && (intv == TIPC_DISC_INACTIVE || intv > TIPC_DISC_FAST)) {
+ d->timer_intv = TIPC_DISC_INIT;
+ mod_timer(&d->timer, jiffies + d->timer_intv);
+ }
+ spin_unlock_bh(&d->lock);
}
-/**
- * disc_timeout - send a periodic link setup request
- * @data: ptr to link request structure
- *
+/* tipc_disc_timeout - send a periodic link setup request
* Called whenever a link setup request timer associated with a bearer expires.
+ * - Keep doubling time between sent request until limit is reached;
+ * - Hold at fast polling rate if we don't have any associated nodes
+ * - Otherwise hold at slow polling rate
*/
-static void disc_timeout(struct timer_list *t)
+static void tipc_disc_timeout(struct timer_list *t)
{
- struct tipc_link_req *req = from_timer(req, t, timer);
- struct sk_buff *skb;
- int max_delay;
+ struct tipc_discoverer *d = from_timer(d, t, timer);
+ struct tipc_media_addr maddr;
+ struct sk_buff *skb = NULL;
+ struct net *net;
+ u32 bearer_id;
- spin_lock_bh(&req->lock);
+ spin_lock_bh(&d->lock);
/* Stop searching if only desired node has been found */
- if (tipc_node(req->domain) && req->num_nodes) {
- req->timer_intv = TIPC_LINK_REQ_INACTIVE;
+ if (tipc_node(d->domain) && d->num_nodes) {
+ d->timer_intv = TIPC_DISC_INACTIVE;
goto exit;
}
-
- /*
- * Send discovery message, then update discovery timer
- *
- * Keep doubling time between requests until limit is reached;
- * hold at fast polling rate if don't have any associated nodes,
- * otherwise hold at slow polling rate
- */
- skb = skb_clone(req->buf, GFP_ATOMIC);
- if (skb)
- tipc_bearer_xmit_skb(req->net, req->bearer_id, skb, &req->dest);
- req->timer_intv *= 2;
- if (req->num_nodes)
- max_delay = TIPC_LINK_REQ_SLOW;
- else
- max_delay = TIPC_LINK_REQ_FAST;
- if (req->timer_intv > max_delay)
- req->timer_intv = max_delay;
-
- mod_timer(&req->timer, jiffies + req->timer_intv);
+ /* Adjust timeout interval according to discovery phase */
+ d->timer_intv *= 2;
+ if (d->num_nodes && d->timer_intv > TIPC_DISC_SLOW)
+ d->timer_intv = TIPC_DISC_SLOW;
+ else if (!d->num_nodes && d->timer_intv > TIPC_DISC_FAST)
+ d->timer_intv = TIPC_DISC_FAST;
+ mod_timer(&d->timer, jiffies + d->timer_intv);
+ memcpy(&maddr, &d->dest, sizeof(maddr));
+ skb = skb_clone(d->skb, GFP_ATOMIC);
+ net = d->net;
+ bearer_id = d->bearer_id;
exit:
- spin_unlock_bh(&req->lock);
+ spin_unlock_bh(&d->lock);
+ if (skb)
+ tipc_bearer_xmit_skb(net, bearer_id, skb, &maddr);
}
/**
@@ -273,41 +260,41 @@ static void disc_timeout(struct timer_list *t)
int tipc_disc_create(struct net *net, struct tipc_bearer *b,
struct tipc_media_addr *dest, struct sk_buff **skb)
{
- struct tipc_link_req *req;
+ struct tipc_discoverer *d;
- req = kmalloc(sizeof(*req), GFP_ATOMIC);
- if (!req)
+ d = kmalloc(sizeof(*d), GFP_ATOMIC);
+ if (!d)
return -ENOMEM;
- req->buf = tipc_buf_acquire(MAX_H_SIZE, GFP_ATOMIC);
- if (!req->buf) {
- kfree(req);
+ d->skb = tipc_buf_acquire(MAX_H_SIZE, GFP_ATOMIC);
+ if (!d->skb) {
+ kfree(d);
return -ENOMEM;
}
- tipc_disc_init_msg(net, req->buf, DSC_REQ_MSG, b);
- memcpy(&req->dest, dest, sizeof(*dest));
- req->net = net;
- req->bearer_id = b->identity;
- req->domain = b->domain;
- req->num_nodes = 0;
- req->timer_intv = TIPC_LINK_REQ_INIT;
- spin_lock_init(&req->lock);
- timer_setup(&req->timer, disc_timeout, 0);
- mod_timer(&req->timer, jiffies + req->timer_intv);
- b->link_req = req;
- *skb = skb_clone(req->buf, GFP_ATOMIC);
+ tipc_disc_init_msg(net, d->skb, DSC_REQ_MSG, b);
+ memcpy(&d->dest, dest, sizeof(*dest));
+ d->net = net;
+ d->bearer_id = b->identity;
+ d->domain = b->domain;
+ d->num_nodes = 0;
+ d->timer_intv = TIPC_DISC_INIT;
+ spin_lock_init(&d->lock);
+ timer_setup(&d->timer, tipc_disc_timeout, 0);
+ mod_timer(&d->timer, jiffies + d->timer_intv);
+ b->disc = d;
+ *skb = skb_clone(d->skb, GFP_ATOMIC);
return 0;
}
/**
* tipc_disc_delete - destroy object sending periodic link setup requests
- * @req: ptr to link request structure
+ * @d: ptr to link duest structure
*/
-void tipc_disc_delete(struct tipc_link_req *req)
+void tipc_disc_delete(struct tipc_discoverer *d)
{
- del_timer_sync(&req->timer);
- kfree_skb(req->buf);
- kfree(req);
+ del_timer_sync(&d->timer);
+ kfree_skb(d->skb);
+ kfree(d);
}
/**
@@ -318,19 +305,21 @@ void tipc_disc_delete(struct tipc_link_req *req)
*/
void tipc_disc_reset(struct net *net, struct tipc_bearer *b)
{
- struct tipc_link_req *req = b->link_req;
+ struct tipc_discoverer *d = b->disc;
+ struct tipc_media_addr maddr;
struct sk_buff *skb;
- spin_lock_bh(&req->lock);
- tipc_disc_init_msg(net, req->buf, DSC_REQ_MSG, b);
- req->net = net;
- req->bearer_id = b->identity;
- req->domain = b->domain;
- req->num_nodes = 0;
- req->timer_intv = TIPC_LINK_REQ_INIT;
- mod_timer(&req->timer, jiffies + req->timer_intv);
- skb = skb_clone(req->buf, GFP_ATOMIC);
+ spin_lock_bh(&d->lock);
+ tipc_disc_init_msg(net, d->skb, DSC_REQ_MSG, b);
+ d->net = net;
+ d->bearer_id = b->identity;
+ d->domain = b->domain;
+ d->num_nodes = 0;
+ d->timer_intv = TIPC_DISC_INIT;
+ memcpy(&maddr, &d->dest, sizeof(maddr));
+ mod_timer(&d->timer, jiffies + d->timer_intv);
+ skb = skb_clone(d->skb, GFP_ATOMIC);
+ spin_unlock_bh(&d->lock);
if (skb)
- tipc_bearer_xmit_skb(net, req->bearer_id, skb, &req->dest);
- spin_unlock_bh(&req->lock);
+ tipc_bearer_xmit_skb(net, b->identity, skb, &maddr);
}
diff --git a/net/tipc/discover.h b/net/tipc/discover.h
index b80a335..521d96c 100644
--- a/net/tipc/discover.h
+++ b/net/tipc/discover.h
@@ -37,14 +37,14 @@
#ifndef _TIPC_DISCOVER_H
#define _TIPC_DISCOVER_H
-struct tipc_link_req;
+struct tipc_discoverer;
int tipc_disc_create(struct net *net, struct tipc_bearer *b_ptr,
struct tipc_media_addr *dest, struct sk_buff **skb);
-void tipc_disc_delete(struct tipc_link_req *req);
+void tipc_disc_delete(struct tipc_discoverer *req);
void tipc_disc_reset(struct net *net, struct tipc_bearer *b_ptr);
-void tipc_disc_add_dest(struct tipc_link_req *req);
-void tipc_disc_remove_dest(struct tipc_link_req *req);
+void tipc_disc_add_dest(struct tipc_discoverer *req);
+void tipc_disc_remove_dest(struct tipc_discoverer *req);
void tipc_disc_rcv(struct net *net, struct sk_buff *buf,
struct tipc_bearer *b_ptr);
--
2.1.4
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
^ permalink raw reply related
* [net-next 3/8] tipc: remove restrictions on node address values
From: Jon Maloy @ 2018-03-22 19:42 UTC (permalink / raw)
To: davem, netdev; +Cc: tipc-discussion, mohan.krishna.ghanta.krishnamurthy
In-Reply-To: <1521747772-7727-1-git-send-email-jon.maloy@ericsson.com>
Nominally, TIPC organizes network nodes into a three-level network
hierarchy consisting of the levels 'zone', 'cluster' and 'node'. This
hierarchy is reflected in the node address format, - it is sub-divided
into an 8-bit zone id, and 12 bit cluster id, and a 12-bit node id.
However, the 'zone' and 'cluster' levels have in reality never been
fully implemented,and never will be. The result of this has been
that the first 20 bits the node identity structure have been wasted,
and the usable node identity range within a cluster has been limited
to 12 bits. This is starting to become a problem.
In the following commits, we will need to be able to connect between
nodes which are using the whole 32-bit value space of the node address.
We therefore remove the restrictions on which values can be assigned
to node identity, -it is from now on only a 32-bit integer with no
assumed internal structure.
Isolation between clusters is now achieved only by setting different
values for the 'network id' field used during neighbor discovery, in
practice leading to the latter becoming the new cluster identity.
The rules for accepting discovery requests/responses from neighboring
nodes now become:
- If the user is using legacy address format on both peers, reception
of discovery messages is subject to the legacy lookup domain check
in addition to the cluster id check.
- Otherwise, the discovery request/response is always accepted, provided
both peers have the same network id.
This secures backwards compatibility for users who have been using zone
or cluster identities as cluster separators, instead of the intended
'network id'.
Acked-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
---
net/tipc/addr.c | 50 +-------------------------------------------------
net/tipc/addr.h | 11 -----------
net/tipc/bearer.c | 27 ++++-----------------------
net/tipc/discover.c | 15 +++++++--------
net/tipc/link.c | 6 ++----
net/tipc/net.c | 4 ++--
net/tipc/node.c | 8 ++------
net/tipc/node.h | 5 +++--
8 files changed, 21 insertions(+), 105 deletions(-)
diff --git a/net/tipc/addr.c b/net/tipc/addr.c
index 97cd857..dfc31a7 100644
--- a/net/tipc/addr.c
+++ b/net/tipc/addr.c
@@ -39,21 +39,6 @@
#include "core.h"
/**
- * in_own_cluster - test for cluster inclusion; <0.0.0> always matches
- */
-int in_own_cluster(struct net *net, u32 addr)
-{
- return in_own_cluster_exact(net, addr) || !addr;
-}
-
-int in_own_cluster_exact(struct net *net, u32 addr)
-{
- struct tipc_net *tn = net_generic(net, tipc_net_id);
-
- return !((addr ^ tn->own_addr) >> 12);
-}
-
-/**
* in_own_node - test for node inclusion; <0.0.0> always matches
*/
int in_own_node(struct net *net, u32 addr)
@@ -63,46 +48,13 @@ int in_own_node(struct net *net, u32 addr)
return (addr == tn->own_addr) || !addr;
}
-/**
- * tipc_addr_domain_valid - validates a network domain address
- *
- * Accepts <Z.C.N>, <Z.C.0>, <Z.0.0>, and <0.0.0>,
- * where Z, C, and N are non-zero.
- *
- * Returns 1 if domain address is valid, otherwise 0
- */
-int tipc_addr_domain_valid(u32 addr)
-{
- u32 n = tipc_node(addr);
- u32 c = tipc_cluster(addr);
- u32 z = tipc_zone(addr);
-
- if (n && (!z || !c))
- return 0;
- if (c && !z)
- return 0;
- return 1;
-}
-
-/**
- * tipc_addr_node_valid - validates a proposed network address for this node
- *
- * Accepts <Z.C.N>, where Z, C, and N are non-zero.
- *
- * Returns 1 if address can be used, otherwise 0
- */
-int tipc_addr_node_valid(u32 addr)
-{
- return tipc_addr_domain_valid(addr) && tipc_node(addr);
-}
-
int tipc_in_scope(u32 domain, u32 addr)
{
if (!domain || (domain == addr))
return 1;
if (domain == tipc_cluster_mask(addr)) /* domain <Z.C.0> */
return 1;
- if (domain == tipc_zone_mask(addr)) /* domain <Z.0.0> */
+ if (domain == (addr & TIPC_ZONE_MASK)) /* domain <Z.0.0> */
return 1;
return 0;
}
diff --git a/net/tipc/addr.h b/net/tipc/addr.h
index 2ecf5a5..5ffde51 100644
--- a/net/tipc/addr.h
+++ b/net/tipc/addr.h
@@ -50,11 +50,6 @@ static inline u32 tipc_own_addr(struct net *net)
return tn->own_addr;
}
-static inline u32 tipc_zone_mask(u32 addr)
-{
- return addr & TIPC_ZONE_MASK;
-}
-
static inline u32 tipc_cluster_mask(u32 addr)
{
return addr & TIPC_ZONE_CLUSTER_MASK;
@@ -71,14 +66,8 @@ static inline int tipc_scope2node(struct net *net, int sc)
}
u32 tipc_own_addr(struct net *net);
-int in_own_cluster(struct net *net, u32 addr);
-int in_own_cluster_exact(struct net *net, u32 addr);
int in_own_node(struct net *net, u32 addr);
-u32 addr_domain(struct net *net, u32 sc);
-int tipc_addr_domain_valid(u32);
-int tipc_addr_node_valid(u32 addr);
int tipc_in_scope(u32 domain, u32 addr);
-int tipc_addr_scope(u32 domain);
char *tipc_addr_string_fill(char *string, u32 addr);
#endif
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 76340b9..a71f318 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -240,7 +240,6 @@ static int tipc_enable_bearer(struct net *net, const char *name,
struct tipc_bearer *b;
struct tipc_media *m;
struct sk_buff *skb;
- char addr_string[16];
int bearer_id = 0;
int res = -EINVAL;
char *errstr = "";
@@ -256,21 +255,6 @@ static int tipc_enable_bearer(struct net *net, const char *name,
goto rejected;
}
- if (tipc_addr_domain_valid(disc_domain) && disc_domain != self) {
- if (tipc_in_scope(disc_domain, self)) {
- /* Accept any node in own cluster */
- disc_domain = self & TIPC_ZONE_CLUSTER_MASK;
- res = 0;
- } else if (in_own_cluster_exact(net, disc_domain)) {
- /* Accept specified node in own cluster */
- res = 0;
- }
- }
- if (res) {
- errstr = "illegal discovery domain";
- goto rejected;
- }
-
if (prio > TIPC_MAX_LINK_PRI && prio != TIPC_MEDIA_LINK_PRI) {
errstr = "illegal priority";
goto rejected;
@@ -354,12 +338,11 @@ static int tipc_enable_bearer(struct net *net, const char *name,
return -ENOMEM;
}
- tipc_addr_string_fill(addr_string, disc_domain);
- pr_info("Enabled bearer <%s>, discovery scope %s, priority %u\n",
- name, addr_string, prio);
+ pr_info("Enabled bearer <%s>, priority %u\n", name, prio);
+
return res;
rejected:
- pr_warn("Bearer <%s> rejected, %s\n", name, errstr);
+ pr_warn("Enabling of bearer <%s> rejected, %s\n", name, errstr);
return res;
}
@@ -865,12 +848,10 @@ int __tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info)
char *bearer;
struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1];
struct net *net = sock_net(skb->sk);
- struct tipc_net *tn = net_generic(net, tipc_net_id);
- u32 domain;
+ u32 domain = 0;
u32 prio;
prio = TIPC_MEDIA_LINK_PRI;
- domain = tn->own_addr & TIPC_ZONE_CLUSTER_MASK;
if (!info->attrs[TIPC_NLA_BEARER])
return -EINVAL;
diff --git a/net/tipc/discover.c b/net/tipc/discover.c
index 09f7555..669af12 100644
--- a/net/tipc/discover.c
+++ b/net/tipc/discover.c
@@ -161,18 +161,17 @@ void tipc_disc_rcv(struct net *net, struct sk_buff *skb,
return;
if (net_id != tn->net_id)
return;
- if (!tipc_addr_domain_valid(dst))
- return;
- if (!tipc_addr_node_valid(src))
- return;
if (in_own_node(net, src)) {
disc_dupl_alert(b, self, &maddr);
return;
}
- if (!tipc_in_scope(dst, self))
- return;
- if (!tipc_in_scope(b->domain, src))
- return;
+ /* Domain filter only works if both peers use legacy address format */
+ if (b->domain) {
+ if (!tipc_in_scope(dst, self))
+ return;
+ if (!tipc_in_scope(b->domain, src))
+ return;
+ }
tipc_node_check_dest(net, src, b, caps, signature,
&maddr, &respond, &dupl_addr);
if (dupl_addr)
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 3c23046..86fde00 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -434,7 +434,7 @@ char *tipc_link_name(struct tipc_link *l)
*/
bool tipc_link_create(struct net *net, char *if_name, int bearer_id,
int tolerance, char net_plane, u32 mtu, int priority,
- int window, u32 session, u32 ownnode, u32 peer,
+ int window, u32 session, u32 self, u32 peer,
u16 peer_caps,
struct tipc_link *bc_sndlink,
struct tipc_link *bc_rcvlink,
@@ -451,9 +451,7 @@ bool tipc_link_create(struct net *net, char *if_name, int bearer_id,
l->session = session;
/* Note: peer i/f name is completed by reset/activate message */
- sprintf(l->name, "%u.%u.%u:%s-%u.%u.%u:unknown",
- tipc_zone(ownnode), tipc_cluster(ownnode), tipc_node(ownnode),
- if_name, tipc_zone(peer), tipc_cluster(peer), tipc_node(peer));
+ sprintf(l->name, "%x:%s-%x:unknown", self, if_name, peer);
strcpy(l->if_name, if_name);
l->addr = peer;
l->peer_caps = peer_caps;
diff --git a/net/tipc/net.c b/net/tipc/net.c
index 5c4c440..a074f28 100644
--- a/net/tipc/net.c
+++ b/net/tipc/net.c
@@ -121,7 +121,7 @@ int tipc_net_start(struct net *net, u32 addr)
TIPC_CLUSTER_SCOPE, 0, tn->own_addr);
pr_info("Started in network mode\n");
- pr_info("Own node address %s, network identity %u\n",
+ pr_info("Own node address %s, cluster identity %u\n",
tipc_addr_string_fill(addr_string, tn->own_addr),
tn->net_id);
return 0;
@@ -238,7 +238,7 @@ int __tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info)
return -EPERM;
addr = nla_get_u32(attrs[TIPC_NLA_NET_ADDR]);
- if (!tipc_addr_node_valid(addr))
+ if (!addr)
return -EINVAL;
tipc_net_start(net, addr);
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 389193d..8a4b049 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -233,9 +233,6 @@ static struct tipc_node *tipc_node_find(struct net *net, u32 addr)
struct tipc_node *node;
unsigned int thash = tipc_hashfn(addr);
- if (unlikely(!in_own_cluster_exact(net, addr)))
- return NULL;
-
rcu_read_lock();
hlist_for_each_entry_rcu(node, &tn->node_htable[thash], hash) {
if (node->addr != addr)
@@ -836,10 +833,9 @@ void tipc_node_check_dest(struct net *net, u32 onode,
/* Now create new link if not already existing */
if (!l) {
- if (n->link_cnt == 2) {
- pr_warn("Cannot establish 3rd link to %x\n", n->addr);
+ if (n->link_cnt == 2)
goto exit;
- }
+
if_name = strchr(b->name, ':') + 1;
if (!tipc_link_create(net, if_name, b->identity, b->tolerance,
b->net_plane, b->mtu, b->priority,
diff --git a/net/tipc/node.h b/net/tipc/node.h
index 4ce5e3a..5fb38cf 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -49,13 +49,14 @@ enum {
TIPC_BCAST_STATE_NACK = (1 << 2),
TIPC_BLOCK_FLOWCTL = (1 << 3),
TIPC_BCAST_RCAST = (1 << 4),
- TIPC_MCAST_GROUPS = (1 << 5)
+ TIPC_NODE_ID32 = (1 << 5)
};
#define TIPC_NODE_CAPABILITIES (TIPC_BCAST_SYNCH | \
TIPC_BCAST_STATE_NACK | \
TIPC_BCAST_RCAST | \
- TIPC_BLOCK_FLOWCTL)
+ TIPC_BLOCK_FLOWCTL | \
+ TIPC_NODE_ID32)
#define INVALID_BEARER_ID -1
void tipc_node_stop(struct net *net);
--
2.1.4
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
^ permalink raw reply related
* [net-next 4/8] tipc: allow closest-first lookup algorithm when legacy address is configured
From: Jon Maloy @ 2018-03-22 19:42 UTC (permalink / raw)
To: davem, netdev; +Cc: tipc-discussion, mohan.krishna.ghanta.krishnamurthy
In-Reply-To: <1521747772-7727-1-git-send-email-jon.maloy@ericsson.com>
The removal of an internal structure of the node address has an unwanted
side effect.
- Currently, if a user is sending an anycast message with destination
domain 0, the tipc_namebl_translate() function will use the 'closest-
first' algorithm to first look for a node local destination, and only
when no such is found, will it resort to the cluster global 'round-
robin' lookup algorithm.
- Current users can get around this, and enforce unconditional use of
global round-robin by indicating a destination as Z.0.0 or Z.C.0.
- This option disappears when we make the node address flat, since the
lookup algorithm has no way of recognizing this case. So, as long as
there are node local destinations, the algorithm will always select
one of those, and there is nothing the sender can do to change this.
We solve this by eliminating the 'closest-first' option, which was never
a good idea anyway, for non-legacy users, but only for those. To
distinguish between legacy users and non-legacy users we introduce a new
flag 'legacy_addr_format' in struct tipc_core, to be set when the user
configures a legacy-style Z.C.N node address. Hence, when a legacy user
indicates a zero lookup domain 'closest-first' is selected, and in all
other cases we use 'round-robin'.
Acked-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
---
net/tipc/addr.c | 12 +++++++-----
net/tipc/addr.h | 2 +-
net/tipc/core.h | 3 ++-
net/tipc/discover.c | 13 ++++++-------
net/tipc/name_table.c | 8 +++++---
net/tipc/net.c | 2 +-
6 files changed, 22 insertions(+), 18 deletions(-)
diff --git a/net/tipc/addr.c b/net/tipc/addr.c
index dfc31a7..1998799 100644
--- a/net/tipc/addr.c
+++ b/net/tipc/addr.c
@@ -48,15 +48,17 @@ int in_own_node(struct net *net, u32 addr)
return (addr == tn->own_addr) || !addr;
}
-int tipc_in_scope(u32 domain, u32 addr)
+bool tipc_in_scope(bool legacy_format, u32 domain, u32 addr)
{
if (!domain || (domain == addr))
- return 1;
+ return true;
+ if (!legacy_format)
+ return false;
if (domain == tipc_cluster_mask(addr)) /* domain <Z.C.0> */
- return 1;
+ return true;
if (domain == (addr & TIPC_ZONE_MASK)) /* domain <Z.0.0> */
- return 1;
- return 0;
+ return true;
+ return false;
}
char *tipc_addr_string_fill(char *string, u32 addr)
diff --git a/net/tipc/addr.h b/net/tipc/addr.h
index 5ffde51..97bdc0e 100644
--- a/net/tipc/addr.h
+++ b/net/tipc/addr.h
@@ -67,7 +67,7 @@ static inline int tipc_scope2node(struct net *net, int sc)
u32 tipc_own_addr(struct net *net);
int in_own_node(struct net *net, u32 addr);
-int tipc_in_scope(u32 domain, u32 addr);
+bool tipc_in_scope(bool legacy_format, u32 domain, u32 addr);
char *tipc_addr_string_fill(char *string, u32 addr);
#endif
diff --git a/net/tipc/core.h b/net/tipc/core.h
index 347f850..bd2b112 100644
--- a/net/tipc/core.h
+++ b/net/tipc/core.h
@@ -1,7 +1,7 @@
/*
* net/tipc/core.h: Include file for TIPC global declarations
*
- * Copyright (c) 2005-2006, 2013 Ericsson AB
+ * Copyright (c) 2005-2006, 2013-2018 Ericsson AB
* Copyright (c) 2005-2007, 2010-2013, Wind River Systems
* All rights reserved.
*
@@ -81,6 +81,7 @@ struct tipc_net {
u32 own_addr;
int net_id;
int random;
+ bool legacy_addr_format;
/* Node table and node list */
spinlock_t node_list_lock;
diff --git a/net/tipc/discover.c b/net/tipc/discover.c
index 669af12..82556e1 100644
--- a/net/tipc/discover.c
+++ b/net/tipc/discover.c
@@ -139,6 +139,7 @@ void tipc_disc_rcv(struct net *net, struct sk_buff *skb,
struct tipc_net *tn = tipc_net(net);
struct tipc_msg *hdr = buf_msg(skb);
u16 caps = msg_node_capabilities(hdr);
+ bool legacy = tn->legacy_addr_format;
u32 signature = msg_node_sig(hdr);
u32 dst = msg_dest_domain(hdr);
u32 net_id = msg_bc_netid(hdr);
@@ -165,13 +166,11 @@ void tipc_disc_rcv(struct net *net, struct sk_buff *skb,
disc_dupl_alert(b, self, &maddr);
return;
}
- /* Domain filter only works if both peers use legacy address format */
- if (b->domain) {
- if (!tipc_in_scope(dst, self))
- return;
- if (!tipc_in_scope(b->domain, src))
- return;
- }
+ if (!tipc_in_scope(legacy, dst, self))
+ return;
+ if (!tipc_in_scope(legacy, b->domain, src))
+ return;
+
tipc_node_check_dest(net, src, b, caps, signature,
&maddr, &respond, &dupl_addr);
if (dupl_addr)
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index bbbfc07..7478acb 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -499,7 +499,9 @@ struct publication *tipc_nametbl_remove_publ(struct net *net, u32 type,
u32 tipc_nametbl_translate(struct net *net, u32 type, u32 instance,
u32 *destnode)
{
- struct tipc_net *tn = net_generic(net, tipc_net_id);
+ struct tipc_net *tn = tipc_net(net);
+ bool legacy = tn->legacy_addr_format;
+ u32 self = tipc_own_addr(net);
struct sub_seq *sseq;
struct name_info *info;
struct publication *publ;
@@ -507,7 +509,7 @@ u32 tipc_nametbl_translate(struct net *net, u32 type, u32 instance,
u32 port = 0;
u32 node = 0;
- if (!tipc_in_scope(*destnode, tn->own_addr))
+ if (!tipc_in_scope(legacy, *destnode, self))
return 0;
rcu_read_lock();
@@ -521,7 +523,7 @@ u32 tipc_nametbl_translate(struct net *net, u32 type, u32 instance,
info = sseq->info;
/* Closest-First Algorithm */
- if (likely(!*destnode)) {
+ if (legacy && !*destnode) {
if (!list_empty(&info->local_publ)) {
publ = list_first_entry(&info->local_publ,
struct publication,
diff --git a/net/tipc/net.c b/net/tipc/net.c
index a074f28..eb0d7a3 100644
--- a/net/tipc/net.c
+++ b/net/tipc/net.c
@@ -240,7 +240,7 @@ int __tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info)
addr = nla_get_u32(attrs[TIPC_NLA_NET_ADDR]);
if (!addr)
return -EINVAL;
-
+ tn->legacy_addr_format = true;
tipc_net_start(net, addr);
}
--
2.1.4
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
^ permalink raw reply related
* [net-next 5/8] tipc: remove direct accesses to own_addr field in struct tipc_net
From: Jon Maloy @ 2018-03-22 19:42 UTC (permalink / raw)
To: davem, netdev; +Cc: tipc-discussion, mohan.krishna.ghanta.krishnamurthy
In-Reply-To: <1521747772-7727-1-git-send-email-jon.maloy@ericsson.com>
As a preparation to changing the addressing structure of TIPC we replace
all direct accesses to the tipc_net::own_addr field with the function
dedicated for this, tipc_own_addr().
There are no changes to program logics in this commit.
Acked-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
---
net/tipc/addr.c | 6 +++---
net/tipc/addr.h | 2 +-
net/tipc/discover.c | 3 ++-
net/tipc/link.c | 9 ++++-----
net/tipc/name_distr.c | 11 ++++++-----
net/tipc/name_table.c | 6 +++---
net/tipc/net.c | 31 +++++++++++++------------------
net/tipc/socket.c | 23 ++++++++++-------------
8 files changed, 42 insertions(+), 49 deletions(-)
diff --git a/net/tipc/addr.c b/net/tipc/addr.c
index 1998799..6e06b4d 100644
--- a/net/tipc/addr.c
+++ b/net/tipc/addr.c
@@ -43,9 +43,7 @@
*/
int in_own_node(struct net *net, u32 addr)
{
- struct tipc_net *tn = net_generic(net, tipc_net_id);
-
- return (addr == tn->own_addr) || !addr;
+ return addr == tipc_own_addr(net) || !addr;
}
bool tipc_in_scope(bool legacy_format, u32 domain, u32 addr)
@@ -56,6 +54,8 @@ bool tipc_in_scope(bool legacy_format, u32 domain, u32 addr)
return false;
if (domain == tipc_cluster_mask(addr)) /* domain <Z.C.0> */
return true;
+ if (domain == (addr & TIPC_ZONE_CLUSTER_MASK)) /* domain <Z.C.0> */
+ return true;
if (domain == (addr & TIPC_ZONE_MASK)) /* domain <Z.0.0> */
return true;
return false;
diff --git a/net/tipc/addr.h b/net/tipc/addr.h
index 97bdc0e..6b48f0d 100644
--- a/net/tipc/addr.h
+++ b/net/tipc/addr.h
@@ -45,7 +45,7 @@
static inline u32 tipc_own_addr(struct net *net)
{
- struct tipc_net *tn = net_generic(net, tipc_net_id);
+ struct tipc_net *tn = tipc_net(net);
return tn->own_addr;
}
diff --git a/net/tipc/discover.c b/net/tipc/discover.c
index 82556e1..94d5240 100644
--- a/net/tipc/discover.c
+++ b/net/tipc/discover.c
@@ -81,11 +81,12 @@ static void tipc_disc_init_msg(struct net *net, struct sk_buff *skb,
u32 mtyp, struct tipc_bearer *b)
{
struct tipc_net *tn = tipc_net(net);
+ u32 self = tipc_own_addr(net);
u32 dest_domain = b->domain;
struct tipc_msg *hdr;
hdr = buf_msg(skb);
- tipc_msg_init(tn->own_addr, hdr, LINK_CONFIG, mtyp,
+ tipc_msg_init(self, hdr, LINK_CONFIG, mtyp,
MAX_H_SIZE, dest_domain);
msg_set_non_seq(hdr, 1);
msg_set_node_sig(hdr, tn->random);
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 86fde00..4aa56e3 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -1936,11 +1936,11 @@ static int __tipc_nl_add_stats(struct sk_buff *skb, struct tipc_stats *s)
int __tipc_nl_add_link(struct net *net, struct tipc_nl_msg *msg,
struct tipc_link *link, int nlflags)
{
- int err;
- void *hdr;
+ u32 self = tipc_own_addr(net);
struct nlattr *attrs;
struct nlattr *prop;
- struct tipc_net *tn = net_generic(net, tipc_net_id);
+ void *hdr;
+ int err;
hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family,
nlflags, TIPC_NL_LINK_GET);
@@ -1953,8 +1953,7 @@ int __tipc_nl_add_link(struct net *net, struct tipc_nl_msg *msg,
if (nla_put_string(msg->skb, TIPC_NLA_LINK_NAME, link->name))
goto attr_msg_full;
- if (nla_put_u32(msg->skb, TIPC_NLA_LINK_DEST,
- tipc_cluster_mask(tn->own_addr)))
+ if (nla_put_u32(msg->skb, TIPC_NLA_LINK_DEST, tipc_cluster_mask(self)))
goto attr_msg_full;
if (nla_put_u32(msg->skb, TIPC_NLA_LINK_MTU, link->mtu))
goto attr_msg_full;
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c
index 28d095a..7e571f4 100644
--- a/net/tipc/name_distr.c
+++ b/net/tipc/name_distr.c
@@ -68,14 +68,14 @@ static void publ_to_item(struct distr_item *i, struct publication *p)
static struct sk_buff *named_prepare_buf(struct net *net, u32 type, u32 size,
u32 dest)
{
- struct tipc_net *tn = net_generic(net, tipc_net_id);
struct sk_buff *buf = tipc_buf_acquire(INT_H_SIZE + size, GFP_ATOMIC);
+ u32 self = tipc_own_addr(net);
struct tipc_msg *msg;
if (buf != NULL) {
msg = buf_msg(buf);
- tipc_msg_init(tn->own_addr, msg, NAME_DISTRIBUTOR, type,
- INT_H_SIZE, dest);
+ tipc_msg_init(self, msg, NAME_DISTRIBUTOR,
+ type, INT_H_SIZE, dest);
msg_set_size(msg, INT_H_SIZE + size);
}
return buf;
@@ -382,13 +382,14 @@ void tipc_named_reinit(struct net *net)
struct name_table *nt = tipc_name_table(net);
struct tipc_net *tn = tipc_net(net);
struct publication *publ;
+ u32 self = tipc_own_addr(net);
spin_lock_bh(&tn->nametbl_lock);
list_for_each_entry_rcu(publ, &nt->node_scope, binding_node)
- publ->node = tn->own_addr;
+ publ->node = self;
list_for_each_entry_rcu(publ, &nt->cluster_scope, binding_node)
- publ->node = tn->own_addr;
+ publ->node = self;
spin_unlock_bh(&tn->nametbl_lock);
}
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index 7478acb..4359605 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -540,7 +540,7 @@ u32 tipc_nametbl_translate(struct net *net, u32 type, u32 instance,
}
/* Round-Robin Algorithm */
- else if (*destnode == tn->own_addr) {
+ else if (*destnode == tipc_own_addr(net)) {
if (list_empty(&info->local_publ))
goto no_match;
publ = list_first_entry(&info->local_publ, struct publication,
@@ -713,7 +713,7 @@ struct publication *tipc_nametbl_publish(struct net *net, u32 type, u32 lower,
}
publ = tipc_nametbl_insert_publ(net, type, lower, upper, scope,
- tn->own_addr, port_ref, key);
+ tipc_own_addr(net), port_ref, key);
if (likely(publ)) {
tn->nametbl->local_publ_count++;
buf = tipc_named_publish(net, publ);
@@ -738,7 +738,7 @@ int tipc_nametbl_withdraw(struct net *net, u32 type, u32 lower, u32 port,
struct tipc_net *tn = net_generic(net, tipc_net_id);
spin_lock_bh(&tn->nametbl_lock);
- publ = tipc_nametbl_remove_publ(net, type, lower, tn->own_addr,
+ publ = tipc_nametbl_remove_publ(net, type, lower, tipc_own_addr(net),
port, key);
if (likely(publ)) {
tn->nametbl->local_publ_count--;
diff --git a/net/tipc/net.c b/net/tipc/net.c
index eb0d7a3..7f140a5 100644
--- a/net/tipc/net.c
+++ b/net/tipc/net.c
@@ -106,7 +106,7 @@
int tipc_net_start(struct net *net, u32 addr)
{
- struct tipc_net *tn = net_generic(net, tipc_net_id);
+ struct tipc_net *tn = tipc_net(net);
char addr_string[16];
tn->own_addr = addr;
@@ -117,25 +117,24 @@ int tipc_net_start(struct net *net, u32 addr)
tipc_named_reinit(net);
tipc_sk_reinit(net);
- tipc_nametbl_publish(net, TIPC_CFG_SRV, tn->own_addr, tn->own_addr,
- TIPC_CLUSTER_SCOPE, 0, tn->own_addr);
+ tipc_nametbl_publish(net, TIPC_CFG_SRV, addr, addr,
+ TIPC_CLUSTER_SCOPE, 0, addr);
pr_info("Started in network mode\n");
pr_info("Own node address %s, cluster identity %u\n",
- tipc_addr_string_fill(addr_string, tn->own_addr),
+ tipc_addr_string_fill(addr_string, addr),
tn->net_id);
return 0;
}
void tipc_net_stop(struct net *net)
{
- struct tipc_net *tn = net_generic(net, tipc_net_id);
+ u32 self = tipc_own_addr(net);
- if (!tn->own_addr)
+ if (!self)
return;
- tipc_nametbl_withdraw(net, TIPC_CFG_SRV, tn->own_addr, 0,
- tn->own_addr);
+ tipc_nametbl_withdraw(net, TIPC_CFG_SRV, self, 0, self);
rtnl_lock();
tipc_bearer_stop(net);
tipc_node_stop(net);
@@ -202,9 +201,9 @@ int tipc_nl_net_dump(struct sk_buff *skb, struct netlink_callback *cb)
int __tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info)
{
- struct net *net = sock_net(skb->sk);
- struct tipc_net *tn = net_generic(net, tipc_net_id);
struct nlattr *attrs[TIPC_NLA_NET_MAX + 1];
+ struct net *net = sock_net(skb->sk);
+ struct tipc_net *tn = tipc_net(net);
int err;
if (!info->attrs[TIPC_NLA_NET])
@@ -216,13 +215,13 @@ int __tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info)
if (err)
return err;
+ /* Can't change net id once TIPC has joined a network */
+ if (tipc_own_addr(net))
+ return -EPERM;
+
if (attrs[TIPC_NLA_NET_ID]) {
u32 val;
- /* Can't change net id once TIPC has joined a network */
- if (tn->own_addr)
- return -EPERM;
-
val = nla_get_u32(attrs[TIPC_NLA_NET_ID]);
if (val < 1 || val > 9999)
return -EINVAL;
@@ -233,10 +232,6 @@ int __tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info)
if (attrs[TIPC_NLA_NET_ADDR]) {
u32 addr;
- /* Can't change net addr once TIPC has joined a network */
- if (tn->own_addr)
- return -EPERM;
-
addr = nla_get_u32(attrs[TIPC_NLA_NET_ADDR]);
if (!addr)
return -EINVAL;
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 732ec89..275b666 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -289,10 +289,9 @@ static bool tipc_sk_type_connectionless(struct sock *sk)
static bool tsk_peer_msg(struct tipc_sock *tsk, struct tipc_msg *msg)
{
struct sock *sk = &tsk->sk;
- struct tipc_net *tn = net_generic(sock_net(sk), tipc_net_id);
+ u32 self = tipc_own_addr(sock_net(sk));
u32 peer_port = tsk_peer_port(tsk);
- u32 orig_node;
- u32 peer_node;
+ u32 orig_node, peer_node;
if (unlikely(!tipc_sk_connected(sk)))
return false;
@@ -306,10 +305,10 @@ static bool tsk_peer_msg(struct tipc_sock *tsk, struct tipc_msg *msg)
if (likely(orig_node == peer_node))
return true;
- if (!orig_node && (peer_node == tn->own_addr))
+ if (!orig_node && peer_node == self)
return true;
- if (!peer_node && (orig_node == tn->own_addr))
+ if (!peer_node && orig_node == self)
return true;
return false;
@@ -461,8 +460,8 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
/* Ensure tsk is visible before we read own_addr. */
smp_mb();
- tipc_msg_init(tn->own_addr, msg, TIPC_LOW_IMPORTANCE, TIPC_NAMED_MSG,
- NAMED_H_SIZE, 0);
+ tipc_msg_init(tipc_own_addr(net), msg, TIPC_LOW_IMPORTANCE,
+ TIPC_NAMED_MSG, NAMED_H_SIZE, 0);
msg_set_origport(msg, tsk->portid);
timer_setup(&sk->sk_timer, tipc_sk_timeout, 0);
@@ -671,7 +670,6 @@ static int tipc_getname(struct socket *sock, struct sockaddr *uaddr,
struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr;
struct sock *sk = sock->sk;
struct tipc_sock *tsk = tipc_sk(sk);
- struct tipc_net *tn = net_generic(sock_net(sock->sk), tipc_net_id);
memset(addr, 0, sizeof(*addr));
if (peer) {
@@ -682,7 +680,7 @@ static int tipc_getname(struct socket *sock, struct sockaddr *uaddr,
addr->addr.id.node = tsk_peer_node(tsk);
} else {
addr->addr.id.ref = tsk->portid;
- addr->addr.id.node = tn->own_addr;
+ addr->addr.id.node = tipc_own_addr(sock_net(sk));
}
addr->addrtype = TIPC_ADDR_ID;
@@ -2667,8 +2665,8 @@ void tipc_sk_reinit(struct net *net)
while ((tsk = rhashtable_walk_next(&iter)) && !IS_ERR(tsk)) {
spin_lock_bh(&tsk->sk.sk_lock.slock);
msg = &tsk->phdr;
- msg_set_prevnode(msg, tn->own_addr);
- msg_set_orignode(msg, tn->own_addr);
+ msg_set_prevnode(msg, tipc_own_addr(net));
+ msg_set_orignode(msg, tipc_own_addr(net));
spin_unlock_bh(&tsk->sk.sk_lock.slock);
}
@@ -3167,11 +3165,10 @@ static int __tipc_nl_add_sk_info(struct sk_buff *skb, struct tipc_sock
*tsk)
{
struct net *net = sock_net(skb->sk);
- struct tipc_net *tn = tipc_net(net);
struct sock *sk = &tsk->sk;
if (nla_put_u32(skb, TIPC_NLA_SOCK_REF, tsk->portid) ||
- nla_put_u32(skb, TIPC_NLA_SOCK_ADDR, tn->own_addr))
+ nla_put_u32(skb, TIPC_NLA_SOCK_ADDR, tipc_own_addr(net)))
return -EMSGSIZE;
if (tipc_sk_connected(sk)) {
--
2.1.4
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
^ permalink raw reply related
* [net-next 6/8] tipc: add 128-bit node identifier
From: Jon Maloy @ 2018-03-22 19:42 UTC (permalink / raw)
To: davem, netdev; +Cc: tipc-discussion, mohan.krishna.ghanta.krishnamurthy
In-Reply-To: <1521747772-7727-1-git-send-email-jon.maloy@ericsson.com>
We add a 128-bit node identity, as an alternative to the currently used
32-bit node address.
For the sake of compatibility and to minimize message header changes
we retain the existing 32-bit address field. When not set explicitly by
the user, this field will be filled with a hash value generated from the
much longer node identity, and be used as a shorthand value for the
latter.
We permit either the address or the identity to be set by configuration,
but not both, so when the address value is set by a legacy user the
corresponding 128-bit node identity is generated based on the that value.
Acked-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
---
include/uapi/linux/tipc_netlink.h | 2 +
net/tipc/addr.c | 81 ++++++++++++++++++++++++++++++++-------
net/tipc/addr.h | 28 +++++++++++---
net/tipc/core.c | 4 +-
net/tipc/core.h | 6 ++-
net/tipc/discover.c | 4 +-
net/tipc/link.c | 6 ++-
net/tipc/name_distr.c | 6 +--
net/tipc/net.c | 51 ++++++++++++++++--------
net/tipc/net.h | 4 +-
net/tipc/node.c | 8 +---
net/tipc/node.h | 4 +-
12 files changed, 148 insertions(+), 56 deletions(-)
diff --git a/include/uapi/linux/tipc_netlink.h b/include/uapi/linux/tipc_netlink.h
index d896ded..0affb68 100644
--- a/include/uapi/linux/tipc_netlink.h
+++ b/include/uapi/linux/tipc_netlink.h
@@ -169,6 +169,8 @@ enum {
TIPC_NLA_NET_UNSPEC,
TIPC_NLA_NET_ID, /* u32 */
TIPC_NLA_NET_ADDR, /* u32 */
+ TIPC_NLA_NET_NODEID, /* u64 */
+ TIPC_NLA_NET_NODEID_W1, /* u64 */
__TIPC_NLA_NET_MAX,
TIPC_NLA_NET_MAX = __TIPC_NLA_NET_MAX - 1
diff --git a/net/tipc/addr.c b/net/tipc/addr.c
index 6e06b4d..4841e98 100644
--- a/net/tipc/addr.c
+++ b/net/tipc/addr.c
@@ -1,7 +1,7 @@
/*
* net/tipc/addr.c: TIPC address utility routines
*
- * Copyright (c) 2000-2006, Ericsson AB
+ * Copyright (c) 2000-2006, 2018, Ericsson AB
* Copyright (c) 2004-2005, 2010-2011, Wind River Systems
* All rights reserved.
*
@@ -34,18 +34,9 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include <linux/kernel.h>
#include "addr.h"
#include "core.h"
-/**
- * in_own_node - test for node inclusion; <0.0.0> always matches
- */
-int in_own_node(struct net *net, u32 addr)
-{
- return addr == tipc_own_addr(net) || !addr;
-}
-
bool tipc_in_scope(bool legacy_format, u32 domain, u32 addr)
{
if (!domain || (domain == addr))
@@ -61,9 +52,71 @@ bool tipc_in_scope(bool legacy_format, u32 domain, u32 addr)
return false;
}
-char *tipc_addr_string_fill(char *string, u32 addr)
+void tipc_set_node_id(struct net *net, u8 *id)
+{
+ struct tipc_net *tn = tipc_net(net);
+ u32 *tmp = (u32 *)id;
+
+ memcpy(tn->node_id, id, NODE_ID_LEN);
+ tipc_nodeid2string(tn->node_id_string, id);
+ tn->node_addr = tmp[0] ^ tmp[1] ^ tmp[2] ^ tmp[3];
+ pr_info("Own node identity %s, cluster identity %u\n",
+ tipc_own_id_string(net), tn->net_id);
+}
+
+void tipc_set_node_addr(struct net *net, u32 addr)
{
- snprintf(string, 16, "<%u.%u.%u>",
- tipc_zone(addr), tipc_cluster(addr), tipc_node(addr));
- return string;
+ struct tipc_net *tn = tipc_net(net);
+ u8 node_id[NODE_ID_LEN] = {0,};
+
+ tn->node_addr = addr;
+ if (!tipc_own_id(net)) {
+ sprintf(node_id, "%x", addr);
+ tipc_set_node_id(net, node_id);
+ }
+ pr_info("32-bit node address hash set to %x\n", addr);
+}
+
+char *tipc_nodeid2string(char *str, u8 *id)
+{
+ int i;
+ u8 c;
+
+ /* Already a string ? */
+ for (i = 0; i < NODE_ID_LEN; i++) {
+ c = id[i];
+ if (c >= '0' && c <= '9')
+ continue;
+ if (c >= 'A' && c <= 'Z')
+ continue;
+ if (c >= 'a' && c <= 'z')
+ continue;
+ if (c == '.')
+ continue;
+ if (c == ':')
+ continue;
+ if (c == '_')
+ continue;
+ if (c == '-')
+ continue;
+ if (c == '@')
+ continue;
+ if (c != 0)
+ break;
+ }
+ if (i == NODE_ID_LEN) {
+ memcpy(str, id, NODE_ID_LEN);
+ str[NODE_ID_LEN] = 0;
+ return str;
+ }
+
+ /* Translate to hex string */
+ for (i = 0; i < NODE_ID_LEN; i++)
+ sprintf(&str[2 * i], "%02x", id[i]);
+
+ /* Strip off trailing zeroes */
+ for (i = NODE_ID_STR_LEN - 2; str[i] == '0'; i--)
+ str[i] = 0;
+
+ return str;
}
diff --git a/net/tipc/addr.h b/net/tipc/addr.h
index 6b48f0d..31bee0e 100644
--- a/net/tipc/addr.h
+++ b/net/tipc/addr.h
@@ -1,7 +1,7 @@
/*
* net/tipc/addr.h: Include file for TIPC address utility routines
*
- * Copyright (c) 2000-2006, Ericsson AB
+ * Copyright (c) 2000-2006, 2018, Ericsson AB
* Copyright (c) 2004-2005, Wind River Systems
* All rights reserved.
*
@@ -45,9 +45,21 @@
static inline u32 tipc_own_addr(struct net *net)
{
+ return tipc_net(net)->node_addr;
+}
+
+static inline u8 *tipc_own_id(struct net *net)
+{
struct tipc_net *tn = tipc_net(net);
- return tn->own_addr;
+ if (!strlen(tn->node_id_string))
+ return NULL;
+ return tn->node_id;
+}
+
+static inline char *tipc_own_id_string(struct net *net)
+{
+ return tipc_net(net)->node_id_string;
}
static inline u32 tipc_cluster_mask(u32 addr)
@@ -65,9 +77,15 @@ static inline int tipc_scope2node(struct net *net, int sc)
return sc != TIPC_NODE_SCOPE ? 0 : tipc_own_addr(net);
}
-u32 tipc_own_addr(struct net *net);
-int in_own_node(struct net *net, u32 addr);
+static inline int in_own_node(struct net *net, u32 addr)
+{
+ return addr == tipc_own_addr(net) || !addr;
+}
+
bool tipc_in_scope(bool legacy_format, u32 domain, u32 addr);
-char *tipc_addr_string_fill(char *string, u32 addr);
+void tipc_set_node_id(struct net *net, u8 *id);
+void tipc_set_node_addr(struct net *net, u32 addr);
+char *tipc_nodeid2string(char *str, u8 *id);
+u32 tipc_node_id2hash(u8 *id128);
#endif
diff --git a/net/tipc/core.c b/net/tipc/core.c
index 04fd91b..e92fed4 100644
--- a/net/tipc/core.c
+++ b/net/tipc/core.c
@@ -56,7 +56,9 @@ static int __net_init tipc_init_net(struct net *net)
int err;
tn->net_id = 4711;
- tn->own_addr = 0;
+ tn->node_addr = 0;
+ memset(tn->node_id, 0, sizeof(tn->node_id));
+ memset(tn->node_id_string, 0, sizeof(tn->node_id_string));
tn->mon_threshold = TIPC_DEF_MON_THRESHOLD;
get_random_bytes(&tn->random, sizeof(int));
INIT_LIST_HEAD(&tn->node_list);
diff --git a/net/tipc/core.h b/net/tipc/core.h
index bd2b112..eabad41 100644
--- a/net/tipc/core.h
+++ b/net/tipc/core.h
@@ -72,13 +72,17 @@ struct tipc_monitor;
#define NODE_HTABLE_SIZE 512
#define MAX_BEARERS 3
#define TIPC_DEF_MON_THRESHOLD 32
+#define NODE_ID_LEN 16
+#define NODE_ID_STR_LEN (NODE_ID_LEN * 2 + 1)
extern unsigned int tipc_net_id __read_mostly;
extern int sysctl_tipc_rmem[3] __read_mostly;
extern int sysctl_tipc_named_timeout __read_mostly;
struct tipc_net {
- u32 own_addr;
+ u8 node_id[NODE_ID_LEN];
+ u32 node_addr;
+ char node_id_string[NODE_ID_STR_LEN];
int net_id;
int random;
bool legacy_addr_format;
diff --git a/net/tipc/discover.c b/net/tipc/discover.c
index 94d5240..b4c4cd1 100644
--- a/net/tipc/discover.c
+++ b/net/tipc/discover.c
@@ -118,13 +118,11 @@ static void tipc_disc_msg_xmit(struct net *net, u32 mtyp, u32 dst, u32 src,
static void disc_dupl_alert(struct tipc_bearer *b, u32 node_addr,
struct tipc_media_addr *media_addr)
{
- char node_addr_str[16];
char media_addr_str[64];
- tipc_addr_string_fill(node_addr_str, node_addr);
tipc_media_addr_printf(media_addr_str, sizeof(media_addr_str),
media_addr);
- pr_warn("Duplicate %s using %s seen on <%s>\n", node_addr_str,
+ pr_warn("Duplicate %x using %s seen on <%s>\n", node_addr,
media_addr_str, b->name);
}
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 4aa56e3..bcd76b1 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -442,6 +442,7 @@ bool tipc_link_create(struct net *net, char *if_name, int bearer_id,
struct sk_buff_head *namedq,
struct tipc_link **link)
{
+ char *self_str = tipc_own_id_string(net);
struct tipc_link *l;
l = kzalloc(sizeof(*l), GFP_ATOMIC);
@@ -451,7 +452,10 @@ bool tipc_link_create(struct net *net, char *if_name, int bearer_id,
l->session = session;
/* Note: peer i/f name is completed by reset/activate message */
- sprintf(l->name, "%x:%s-%x:unknown", self, if_name, peer);
+ if (strlen(self_str) > 16)
+ sprintf(l->name, "%x:%s-%x:unknown", self, if_name, peer);
+ else
+ sprintf(l->name, "%s:%s-%x:unknown", self_str, if_name, peer);
strcpy(l->if_name, if_name);
l->addr = peer;
l->peer_caps = peer_caps;
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c
index 7e571f4..8240a85 100644
--- a/net/tipc/name_distr.c
+++ b/net/tipc/name_distr.c
@@ -318,7 +318,6 @@ void tipc_named_process_backlog(struct net *net)
{
struct distr_queue_item *e, *tmp;
struct tipc_net *tn = net_generic(net, tipc_net_id);
- char addr[16];
unsigned long now = get_jiffies_64();
list_for_each_entry_safe(e, tmp, &tn->dist_queue, next) {
@@ -326,12 +325,11 @@ void tipc_named_process_backlog(struct net *net)
if (!tipc_update_nametbl(net, &e->i, e->node, e->dtype))
continue;
} else {
- tipc_addr_string_fill(addr, e->node);
- pr_warn_ratelimited("Dropping name table update (%d) of {%u, %u, %u} from %s key=%u\n",
+ pr_warn_ratelimited("Dropping name table update (%d) of {%u, %u, %u} from %x key=%u\n",
e->dtype, ntohl(e->i.type),
ntohl(e->i.lower),
ntohl(e->i.upper),
- addr, ntohl(e->i.key));
+ e->node, ntohl(e->i.key));
}
list_del(&e->next);
kfree(e);
diff --git a/net/tipc/net.c b/net/tipc/net.c
index 7f140a5..e786748 100644
--- a/net/tipc/net.c
+++ b/net/tipc/net.c
@@ -104,27 +104,31 @@
* - A local spin_lock protecting the queue of subscriber events.
*/
-int tipc_net_start(struct net *net, u32 addr)
+int tipc_net_init(struct net *net, u8 *node_id, u32 addr)
{
- struct tipc_net *tn = tipc_net(net);
- char addr_string[16];
+ if (tipc_own_id(net)) {
+ pr_info("Cannot configure node identity twice\n");
+ return -1;
+ }
+ pr_info("Started in network mode\n");
- tn->own_addr = addr;
+ if (node_id) {
+ tipc_set_node_id(net, node_id);
+ tipc_net_finalize(net, tipc_own_addr(net));
+ }
+ if (addr)
+ tipc_net_finalize(net, addr);
+ return 0;
+}
- /* Ensure that the new address is visible before we reinit. */
+void tipc_net_finalize(struct net *net, u32 addr)
+{
+ tipc_set_node_addr(net, addr);
smp_mb();
-
tipc_named_reinit(net);
tipc_sk_reinit(net);
-
tipc_nametbl_publish(net, TIPC_CFG_SRV, addr, addr,
TIPC_CLUSTER_SCOPE, 0, addr);
-
- pr_info("Started in network mode\n");
- pr_info("Own node address %s, cluster identity %u\n",
- tipc_addr_string_fill(addr_string, addr),
- tn->net_id);
- return 0;
}
void tipc_net_stop(struct net *net)
@@ -146,8 +150,10 @@ void tipc_net_stop(struct net *net)
static int __tipc_nl_add_net(struct net *net, struct tipc_nl_msg *msg)
{
struct tipc_net *tn = net_generic(net, tipc_net_id);
- void *hdr;
+ u64 *w0 = (u64 *)&tn->node_id[0];
+ u64 *w1 = (u64 *)&tn->node_id[8];
struct nlattr *attrs;
+ void *hdr;
hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family,
NLM_F_MULTI, TIPC_NL_NET_GET);
@@ -160,7 +166,10 @@ static int __tipc_nl_add_net(struct net *net, struct tipc_nl_msg *msg)
if (nla_put_u32(msg->skb, TIPC_NLA_NET_ID, tn->net_id))
goto attr_msg_full;
-
+ if (nla_put_u64_64bit(msg->skb, TIPC_NLA_NET_NODEID, *w0, 0))
+ goto attr_msg_full;
+ if (nla_put_u64_64bit(msg->skb, TIPC_NLA_NET_NODEID_W1, *w1, 0))
+ goto attr_msg_full;
nla_nest_end(msg->skb, attrs);
genlmsg_end(msg->skb, hdr);
@@ -212,6 +221,7 @@ int __tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info)
err = nla_parse_nested(attrs, TIPC_NLA_NET_MAX,
info->attrs[TIPC_NLA_NET], tipc_nl_net_policy,
info->extack);
+
if (err)
return err;
@@ -236,9 +246,18 @@ int __tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info)
if (!addr)
return -EINVAL;
tn->legacy_addr_format = true;
- tipc_net_start(net, addr);
+ tipc_net_init(net, NULL, addr);
}
+ if (attrs[TIPC_NLA_NET_NODEID]) {
+ u8 node_id[NODE_ID_LEN];
+ u64 *w0 = (u64 *)&node_id[0];
+ u64 *w1 = (u64 *)&node_id[8];
+
+ *w0 = nla_get_u64(attrs[TIPC_NLA_NET_NODEID]);
+ *w1 = nla_get_u64(attrs[TIPC_NLA_NET_NODEID_W1]);
+ tipc_net_init(net, node_id, 0);
+ }
return 0;
}
diff --git a/net/tipc/net.h b/net/tipc/net.h
index c0306aa..08efa60 100644
--- a/net/tipc/net.h
+++ b/net/tipc/net.h
@@ -41,10 +41,8 @@
extern const struct nla_policy tipc_nl_net_policy[];
-int tipc_net_start(struct net *net, u32 addr);
-
+void tipc_net_finalize(struct net *net, u32 addr);
void tipc_net_stop(struct net *net);
-
int tipc_nl_net_dump(struct sk_buff *skb, struct netlink_callback *cb);
int tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info);
int __tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info);
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 8a4b049..7b0c993 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -883,11 +883,9 @@ void tipc_node_delete_links(struct net *net, int bearer_id)
static void tipc_node_reset_links(struct tipc_node *n)
{
- char addr_string[16];
int i;
- pr_warn("Resetting all links to %s\n",
- tipc_addr_string_fill(addr_string, n->addr));
+ pr_warn("Resetting all links to %x\n", n->addr);
for (i = 0; i < MAX_BEARERS; i++) {
tipc_node_link_down(n, i, false);
@@ -1074,15 +1072,13 @@ static void tipc_node_fsm_evt(struct tipc_node *n, int evt)
static void node_lost_contact(struct tipc_node *n,
struct sk_buff_head *inputq)
{
- char addr_string[16];
struct tipc_sock_conn *conn, *safe;
struct tipc_link *l;
struct list_head *conns = &n->conn_sks;
struct sk_buff *skb;
uint i;
- pr_debug("Lost contact with %s\n",
- tipc_addr_string_fill(addr_string, n->addr));
+ pr_debug("Lost contact with %x\n", n->addr);
/* Clean up broadcast state */
tipc_bcast_remove_peer(n->net, n->bc_entry.link);
diff --git a/net/tipc/node.h b/net/tipc/node.h
index 5fb38cf..e06faf4 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -49,14 +49,14 @@ enum {
TIPC_BCAST_STATE_NACK = (1 << 2),
TIPC_BLOCK_FLOWCTL = (1 << 3),
TIPC_BCAST_RCAST = (1 << 4),
- TIPC_NODE_ID32 = (1 << 5)
+ TIPC_NODE_ID128 = (1 << 5)
};
#define TIPC_NODE_CAPABILITIES (TIPC_BCAST_SYNCH | \
TIPC_BCAST_STATE_NACK | \
TIPC_BCAST_RCAST | \
TIPC_BLOCK_FLOWCTL | \
- TIPC_NODE_ID32)
+ TIPC_NODE_ID128)
#define INVALID_BEARER_ID -1
void tipc_node_stop(struct net *net);
--
2.1.4
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
^ permalink raw reply related
* [net-next 7/8] tipc: handle collisions of 32-bit node address hash values
From: Jon Maloy @ 2018-03-22 19:42 UTC (permalink / raw)
To: davem, netdev; +Cc: tipc-discussion, mohan.krishna.ghanta.krishnamurthy
In-Reply-To: <1521747772-7727-1-git-send-email-jon.maloy@ericsson.com>
When a 32-bit node address is generated from a 128-bit identifier,
there is a risk of collisions which must be discovered and handled.
We do this as follows:
- We don't apply the generated address immediately to the node, but do
instead initiate a 1 sec trial period to allow other cluster members
to discover and handle such collisions.
- During the trial period the node periodically sends out a new type
of message, DSC_TRIAL_MSG, using broadcast or emulated broadcast,
to all the other nodes in the cluster.
- When a node is receiving such a message, it must check that the
presented 32-bit identifier either is unused, or was used by the very
same peer in a previous session. In both cases it accepts the request
by not responding to it.
- If it finds that the same node has been up before using a different
address, it responds with a DSC_TRIAL_FAIL_MSG containing that
address.
- If it finds that the address has already been taken by some other
node, it generates a new, unused address and returns it to the
requester.
- During the trial period the requesting node must always be prepared
to accept a failure message, i.e., a message where a peer suggests a
different (or equal) address to the one tried. In those cases it
must apply the suggested value as trial address and restart the trial
period.
This algorithm ensures that in the vast majority of cases a node will
have the same address before and after a reboot. If a legacy user
configures the address explicitly, there will be no trial period and
messages, so this protocol addition is completely backwards compatible.
Acked-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
---
net/tipc/addr.c | 3 +-
net/tipc/bearer.c | 3 +-
net/tipc/core.c | 2 +
net/tipc/core.h | 2 +
net/tipc/discover.c | 126 ++++++++++++++++++++++++++++++++++++++++++++--------
net/tipc/link.c | 26 +++++++----
net/tipc/link.h | 4 +-
net/tipc/msg.h | 23 +++++++++-
net/tipc/net.c | 4 +-
net/tipc/node.c | 85 ++++++++++++++++++++++++++++++++---
net/tipc/node.h | 3 +-
11 files changed, 236 insertions(+), 45 deletions(-)
diff --git a/net/tipc/addr.c b/net/tipc/addr.c
index 4841e98..b88d48d 100644
--- a/net/tipc/addr.c
+++ b/net/tipc/addr.c
@@ -59,7 +59,7 @@ void tipc_set_node_id(struct net *net, u8 *id)
memcpy(tn->node_id, id, NODE_ID_LEN);
tipc_nodeid2string(tn->node_id_string, id);
- tn->node_addr = tmp[0] ^ tmp[1] ^ tmp[2] ^ tmp[3];
+ tn->trial_addr = tmp[0] ^ tmp[1] ^ tmp[2] ^ tmp[3];
pr_info("Own node identity %s, cluster identity %u\n",
tipc_own_id_string(net), tn->net_id);
}
@@ -74,6 +74,7 @@ void tipc_set_node_addr(struct net *net, u32 addr)
sprintf(node_id, "%x", addr);
tipc_set_node_id(net, node_id);
}
+ tn->trial_addr = addr;
pr_info("32-bit node address hash set to %x\n", addr);
}
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index a71f318..ae5b44c 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -235,7 +235,6 @@ static int tipc_enable_bearer(struct net *net, const char *name,
{
struct tipc_net *tn = tipc_net(net);
struct tipc_bearer_names b_names;
- u32 self = tipc_own_addr(net);
int with_this_prio = 1;
struct tipc_bearer *b;
struct tipc_media *m;
@@ -244,7 +243,7 @@ static int tipc_enable_bearer(struct net *net, const char *name,
int res = -EINVAL;
char *errstr = "";
- if (!self) {
+ if (!tipc_own_id(net)) {
errstr = "not supported in standalone mode";
res = -ENOPROTOOPT;
goto rejected;
diff --git a/net/tipc/core.c b/net/tipc/core.c
index e92fed4..52dfc51 100644
--- a/net/tipc/core.c
+++ b/net/tipc/core.c
@@ -57,6 +57,8 @@ static int __net_init tipc_init_net(struct net *net)
tn->net_id = 4711;
tn->node_addr = 0;
+ tn->trial_addr = 0;
+ tn->addr_trial_end = 0;
memset(tn->node_id, 0, sizeof(tn->node_id));
memset(tn->node_id_string, 0, sizeof(tn->node_id_string));
tn->mon_threshold = TIPC_DEF_MON_THRESHOLD;
diff --git a/net/tipc/core.h b/net/tipc/core.h
index eabad41..d0f64ca 100644
--- a/net/tipc/core.h
+++ b/net/tipc/core.h
@@ -82,6 +82,8 @@ extern int sysctl_tipc_named_timeout __read_mostly;
struct tipc_net {
u8 node_id[NODE_ID_LEN];
u32 node_addr;
+ u32 trial_addr;
+ unsigned long addr_trial_end;
char node_id_string[NODE_ID_STR_LEN];
int net_id;
int random;
diff --git a/net/tipc/discover.c b/net/tipc/discover.c
index b4c4cd1..e765573 100644
--- a/net/tipc/discover.c
+++ b/net/tipc/discover.c
@@ -1,7 +1,7 @@
/*
* net/tipc/discover.c
*
- * Copyright (c) 2003-2006, 2014-2015, Ericsson AB
+ * Copyright (c) 2003-2006, 2014-2018, Ericsson AB
* Copyright (c) 2005-2006, 2010-2011, Wind River Systems
* All rights reserved.
*
@@ -78,34 +78,40 @@ struct tipc_discoverer {
* @b: ptr to bearer issuing message
*/
static void tipc_disc_init_msg(struct net *net, struct sk_buff *skb,
- u32 mtyp, struct tipc_bearer *b)
+ u32 mtyp, struct tipc_bearer *b)
{
struct tipc_net *tn = tipc_net(net);
- u32 self = tipc_own_addr(net);
u32 dest_domain = b->domain;
struct tipc_msg *hdr;
hdr = buf_msg(skb);
- tipc_msg_init(self, hdr, LINK_CONFIG, mtyp,
+ tipc_msg_init(tn->trial_addr, hdr, LINK_CONFIG, mtyp,
MAX_H_SIZE, dest_domain);
+ msg_set_size(hdr, MAX_H_SIZE + NODE_ID_LEN);
msg_set_non_seq(hdr, 1);
msg_set_node_sig(hdr, tn->random);
msg_set_node_capabilities(hdr, TIPC_NODE_CAPABILITIES);
msg_set_dest_domain(hdr, dest_domain);
msg_set_bc_netid(hdr, tn->net_id);
b->media->addr2msg(msg_media_addr(hdr), &b->addr);
+ msg_set_node_id(hdr, tipc_own_id(net));
}
-static void tipc_disc_msg_xmit(struct net *net, u32 mtyp, u32 dst, u32 src,
+static void tipc_disc_msg_xmit(struct net *net, u32 mtyp, u32 dst,
+ u32 src, u32 sugg_addr,
struct tipc_media_addr *maddr,
struct tipc_bearer *b)
{
+ struct tipc_msg *hdr;
struct sk_buff *skb;
- skb = tipc_buf_acquire(MAX_H_SIZE, GFP_ATOMIC);
+ skb = tipc_buf_acquire(MAX_H_SIZE + NODE_ID_LEN, GFP_ATOMIC);
if (!skb)
return;
+ hdr = buf_msg(skb);
tipc_disc_init_msg(net, skb, mtyp, b);
+ msg_set_sugg_node_addr(hdr, sugg_addr);
+ msg_set_dest_domain(hdr, dst);
tipc_bearer_xmit_skb(net, b->identity, skb, maddr);
}
@@ -126,6 +132,52 @@ static void disc_dupl_alert(struct tipc_bearer *b, u32 node_addr,
media_addr_str, b->name);
}
+/* tipc_disc_addr_trial(): - handle an address uniqueness trial from peer
+ */
+bool tipc_disc_addr_trial_msg(struct tipc_discoverer *d,
+ struct tipc_media_addr *maddr,
+ struct tipc_bearer *b,
+ u32 dst, u32 src,
+ u32 sugg_addr,
+ u8 *peer_id,
+ int mtyp)
+{
+ struct net *net = d->net;
+ struct tipc_net *tn = tipc_net(net);
+ bool trial = time_before(jiffies, tn->addr_trial_end);
+ u32 self = tipc_own_addr(net);
+
+ if (mtyp == DSC_TRIAL_FAIL_MSG) {
+ if (!trial)
+ return true;
+
+ /* Ignore if somebody else already gave new suggestion */
+ if (dst != tn->trial_addr)
+ return true;
+
+ /* Otherwise update trial address and restart trial period */
+ tn->trial_addr = sugg_addr;
+ msg_set_prevnode(buf_msg(d->skb), sugg_addr);
+ tn->addr_trial_end = jiffies + msecs_to_jiffies(1000);
+ return true;
+ }
+
+ /* Apply trial address if we just left trial period */
+ if (!trial && !self) {
+ tipc_net_finalize(net, tn->trial_addr);
+ msg_set_type(buf_msg(d->skb), DSC_REQ_MSG);
+ }
+
+ if (mtyp != DSC_TRIAL_MSG)
+ return false;
+
+ sugg_addr = tipc_node_try_addr(net, peer_id, src);
+ if (sugg_addr)
+ tipc_disc_msg_xmit(net, DSC_TRIAL_FAIL_MSG, src,
+ self, sugg_addr, maddr, b);
+ return true;
+}
+
/**
* tipc_disc_rcv - handle incoming discovery message (request or response)
* @net: applicable net namespace
@@ -139,17 +191,27 @@ void tipc_disc_rcv(struct net *net, struct sk_buff *skb,
struct tipc_msg *hdr = buf_msg(skb);
u16 caps = msg_node_capabilities(hdr);
bool legacy = tn->legacy_addr_format;
+ u32 sugg = msg_sugg_node_addr(hdr);
u32 signature = msg_node_sig(hdr);
+ u8 peer_id[NODE_ID_LEN] = {0,};
u32 dst = msg_dest_domain(hdr);
u32 net_id = msg_bc_netid(hdr);
- u32 self = tipc_own_addr(net);
struct tipc_media_addr maddr;
u32 src = msg_prevnode(hdr);
u32 mtyp = msg_type(hdr);
bool dupl_addr = false;
bool respond = false;
+ u32 self;
int err;
+ skb_linearize(skb);
+ hdr = buf_msg(skb);
+
+ if (caps & TIPC_NODE_ID128)
+ memcpy(peer_id, msg_node_id(hdr), NODE_ID_LEN);
+ else
+ sprintf(peer_id, "%x", src);
+
err = b->media->msg2addr(b, &maddr, msg_media_addr(hdr));
kfree_skb(skb);
if (err || maddr.broadcast) {
@@ -161,6 +223,12 @@ void tipc_disc_rcv(struct net *net, struct sk_buff *skb,
return;
if (net_id != tn->net_id)
return;
+ if (tipc_disc_addr_trial_msg(b->disc, &maddr, b, dst,
+ src, sugg, peer_id, mtyp))
+ return;
+ self = tipc_own_addr(net);
+
+ /* Message from somebody using this node's address */
if (in_own_node(net, src)) {
disc_dupl_alert(b, self, &maddr);
return;
@@ -169,8 +237,7 @@ void tipc_disc_rcv(struct net *net, struct sk_buff *skb,
return;
if (!tipc_in_scope(legacy, b->domain, src))
return;
-
- tipc_node_check_dest(net, src, b, caps, signature,
+ tipc_node_check_dest(net, src, peer_id, b, caps, signature,
&maddr, &respond, &dupl_addr);
if (dupl_addr)
disc_dupl_alert(b, src, &maddr);
@@ -178,7 +245,7 @@ void tipc_disc_rcv(struct net *net, struct sk_buff *skb,
return;
if (mtyp != DSC_REQ_MSG)
return;
- tipc_disc_msg_xmit(net, DSC_RESP_MSG, src, self, &maddr, b);
+ tipc_disc_msg_xmit(net, DSC_RESP_MSG, src, self, 0, &maddr, b);
}
/* tipc_disc_add_dest - increment set of discovered nodes
@@ -216,9 +283,11 @@ void tipc_disc_remove_dest(struct tipc_discoverer *d)
static void tipc_disc_timeout(struct timer_list *t)
{
struct tipc_discoverer *d = from_timer(d, t, timer);
+ struct tipc_net *tn = tipc_net(d->net);
+ u32 self = tipc_own_addr(d->net);
struct tipc_media_addr maddr;
struct sk_buff *skb = NULL;
- struct net *net;
+ struct net *net = d->net;
u32 bearer_id;
spin_lock_bh(&d->lock);
@@ -228,16 +297,29 @@ static void tipc_disc_timeout(struct timer_list *t)
d->timer_intv = TIPC_DISC_INACTIVE;
goto exit;
}
+
+ /* Did we just leave the address trial period ? */
+ if (!self && !time_before(jiffies, tn->addr_trial_end)) {
+ self = tn->trial_addr;
+ tipc_net_finalize(net, self);
+ msg_set_prevnode(buf_msg(d->skb), self);
+ msg_set_type(buf_msg(d->skb), DSC_REQ_MSG);
+ }
+
/* Adjust timeout interval according to discovery phase */
- d->timer_intv *= 2;
- if (d->num_nodes && d->timer_intv > TIPC_DISC_SLOW)
- d->timer_intv = TIPC_DISC_SLOW;
- else if (!d->num_nodes && d->timer_intv > TIPC_DISC_FAST)
- d->timer_intv = TIPC_DISC_FAST;
+ if (time_before(jiffies, tn->addr_trial_end)) {
+ d->timer_intv = TIPC_DISC_INIT;
+ } else {
+ d->timer_intv *= 2;
+ if (d->num_nodes && d->timer_intv > TIPC_DISC_SLOW)
+ d->timer_intv = TIPC_DISC_SLOW;
+ else if (!d->num_nodes && d->timer_intv > TIPC_DISC_FAST)
+ d->timer_intv = TIPC_DISC_FAST;
+ }
+
mod_timer(&d->timer, jiffies + d->timer_intv);
memcpy(&maddr, &d->dest, sizeof(maddr));
skb = skb_clone(d->skb, GFP_ATOMIC);
- net = d->net;
bearer_id = d->bearer_id;
exit:
spin_unlock_bh(&d->lock);
@@ -257,18 +339,24 @@ static void tipc_disc_timeout(struct timer_list *t)
int tipc_disc_create(struct net *net, struct tipc_bearer *b,
struct tipc_media_addr *dest, struct sk_buff **skb)
{
+ struct tipc_net *tn = tipc_net(net);
struct tipc_discoverer *d;
d = kmalloc(sizeof(*d), GFP_ATOMIC);
if (!d)
return -ENOMEM;
- d->skb = tipc_buf_acquire(MAX_H_SIZE, GFP_ATOMIC);
+ d->skb = tipc_buf_acquire(MAX_H_SIZE + NODE_ID_LEN, GFP_ATOMIC);
if (!d->skb) {
kfree(d);
return -ENOMEM;
}
-
tipc_disc_init_msg(net, d->skb, DSC_REQ_MSG, b);
+
+ /* Do we need an address trial period first ? */
+ if (!tipc_own_addr(net)) {
+ tn->addr_trial_end = jiffies + msecs_to_jiffies(1000);
+ msg_set_type(buf_msg(d->skb), DSC_TRIAL_MSG);
+ }
memcpy(&d->dest, dest, sizeof(*dest));
d->net = net;
d->bearer_id = b->identity;
diff --git a/net/tipc/link.c b/net/tipc/link.c
index bcd76b1..1289b4b 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -434,15 +434,16 @@ char *tipc_link_name(struct tipc_link *l)
*/
bool tipc_link_create(struct net *net, char *if_name, int bearer_id,
int tolerance, char net_plane, u32 mtu, int priority,
- int window, u32 session, u32 self, u32 peer,
- u16 peer_caps,
+ int window, u32 session, u32 self,
+ u32 peer, u8 *peer_id, u16 peer_caps,
struct tipc_link *bc_sndlink,
struct tipc_link *bc_rcvlink,
struct sk_buff_head *inputq,
struct sk_buff_head *namedq,
struct tipc_link **link)
{
- char *self_str = tipc_own_id_string(net);
+ char peer_str[NODE_ID_STR_LEN] = {0,};
+ char self_str[NODE_ID_STR_LEN] = {0,};
struct tipc_link *l;
l = kzalloc(sizeof(*l), GFP_ATOMIC);
@@ -451,11 +452,18 @@ bool tipc_link_create(struct net *net, char *if_name, int bearer_id,
*link = l;
l->session = session;
- /* Note: peer i/f name is completed by reset/activate message */
- if (strlen(self_str) > 16)
- sprintf(l->name, "%x:%s-%x:unknown", self, if_name, peer);
- else
- sprintf(l->name, "%s:%s-%x:unknown", self_str, if_name, peer);
+ /* Set link name for unicast links only */
+ if (peer_id) {
+ tipc_nodeid2string(self_str, tipc_own_id(net));
+ if (strlen(self_str) > 16)
+ sprintf(self_str, "%x", self);
+ tipc_nodeid2string(peer_str, peer_id);
+ if (strlen(peer_str) > 16)
+ sprintf(peer_str, "%x", peer);
+ }
+ /* Peer i/f name will be completed by reset/activate message */
+ sprintf(l->name, "%s:%s-%s:unknown", self_str, if_name, peer_str);
+
strcpy(l->if_name, if_name);
l->addr = peer;
l->peer_caps = peer_caps;
@@ -503,7 +511,7 @@ bool tipc_link_bc_create(struct net *net, u32 ownnode, u32 peer,
struct tipc_link *l;
if (!tipc_link_create(net, "", MAX_BEARERS, 0, 'Z', mtu, 0, window,
- 0, ownnode, peer, peer_caps, bc_sndlink,
+ 0, ownnode, peer, NULL, peer_caps, bc_sndlink,
NULL, inputq, namedq, link))
return false;
diff --git a/net/tipc/link.h b/net/tipc/link.h
index d1bd178..ec59348 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -73,8 +73,8 @@ enum {
bool tipc_link_create(struct net *net, char *if_name, int bearer_id,
int tolerance, char net_plane, u32 mtu, int priority,
- int window, u32 session, u32 ownnode, u32 peer,
- u16 peer_caps,
+ int window, u32 session, u32 ownnode,
+ u32 peer, u8 *peer_id, u16 peer_caps,
struct tipc_link *bc_sndlink,
struct tipc_link *bc_rcvlink,
struct sk_buff_head *inputq,
diff --git a/net/tipc/msg.h b/net/tipc/msg.h
index b4ba1b4..a4e944d 100644
--- a/net/tipc/msg.h
+++ b/net/tipc/msg.h
@@ -550,6 +550,8 @@ static inline void msg_set_nameupper(struct tipc_msg *m, u32 n)
*/
#define DSC_REQ_MSG 0
#define DSC_RESP_MSG 1
+#define DSC_TRIAL_MSG 2
+#define DSC_TRIAL_FAIL_MSG 3
/*
* Group protocol message types
@@ -627,7 +629,6 @@ static inline void msg_set_bcgap_to(struct tipc_msg *m, u32 n)
msg_set_bits(m, 2, 0, 0xffff, n);
}
-
/*
* Word 4
*/
@@ -925,6 +926,26 @@ static inline bool msg_is_reset(struct tipc_msg *hdr)
return (msg_user(hdr) == LINK_PROTOCOL) && (msg_type(hdr) == RESET_MSG);
}
+static inline u32 msg_sugg_node_addr(struct tipc_msg *m)
+{
+ return msg_word(m, 14);
+}
+
+static inline void msg_set_sugg_node_addr(struct tipc_msg *m, u32 n)
+{
+ msg_set_word(m, 14, n);
+}
+
+static inline void msg_set_node_id(struct tipc_msg *hdr, u8 *id)
+{
+ memcpy(msg_data(hdr), id, 16);
+}
+
+static inline u8 *msg_node_id(struct tipc_msg *hdr)
+{
+ return (u8 *)msg_data(hdr);
+}
+
struct sk_buff *tipc_buf_acquire(u32 size, gfp_t gfp);
bool tipc_msg_validate(struct sk_buff **_skb);
bool tipc_msg_reverse(u32 own_addr, struct sk_buff **skb, int err);
diff --git a/net/tipc/net.c b/net/tipc/net.c
index e786748..29538dc 100644
--- a/net/tipc/net.c
+++ b/net/tipc/net.c
@@ -112,10 +112,8 @@ int tipc_net_init(struct net *net, u8 *node_id, u32 addr)
}
pr_info("Started in network mode\n");
- if (node_id) {
+ if (node_id)
tipc_set_node_id(net, node_id);
- tipc_net_finalize(net, tipc_own_addr(net));
- }
if (addr)
tipc_net_finalize(net, addr);
return 0;
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 7b0c993..4a95c8c 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -115,6 +115,7 @@ struct tipc_node {
u16 capabilities;
u32 signature;
u32 link_id;
+ u8 peer_id[16];
struct list_head publ_list;
struct list_head conn_sks;
unsigned long keepalive_intv;
@@ -156,6 +157,7 @@ static void tipc_node_delete(struct tipc_node *node);
static void tipc_node_timeout(struct timer_list *t);
static void tipc_node_fsm_evt(struct tipc_node *n, int evt);
static struct tipc_node *tipc_node_find(struct net *net, u32 addr);
+static struct tipc_node *tipc_node_find_by_id(struct net *net, u8 *id);
static void tipc_node_put(struct tipc_node *node);
static bool node_is_up(struct tipc_node *n);
@@ -245,6 +247,30 @@ static struct tipc_node *tipc_node_find(struct net *net, u32 addr)
return node;
}
+/* tipc_node_find_by_id - locate specified node object by its 128-bit id
+ * Note: this function is called only when a discovery request failed
+ * to find the node by its 32-bit id, and is not time critical
+ */
+static struct tipc_node *tipc_node_find_by_id(struct net *net, u8 *id)
+{
+ struct tipc_net *tn = tipc_net(net);
+ struct tipc_node *n;
+ bool found = false;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(n, &tn->node_list, list) {
+ read_lock_bh(&n->lock);
+ if (!memcmp(id, n->peer_id, 16) &&
+ kref_get_unless_zero(&n->kref))
+ found = true;
+ read_unlock_bh(&n->lock);
+ if (found)
+ break;
+ }
+ rcu_read_unlock();
+ return found ? n : NULL;
+}
+
static void tipc_node_read_lock(struct tipc_node *n)
{
read_lock_bh(&n->lock);
@@ -307,7 +333,8 @@ static void tipc_node_write_unlock(struct tipc_node *n)
}
}
-struct tipc_node *tipc_node_create(struct net *net, u32 addr, u16 capabilities)
+struct tipc_node *tipc_node_create(struct net *net, u32 addr,
+ u8 *peer_id, u16 capabilities)
{
struct tipc_net *tn = net_generic(net, tipc_net_id);
struct tipc_node *n, *temp_node;
@@ -326,6 +353,7 @@ struct tipc_node *tipc_node_create(struct net *net, u32 addr, u16 capabilities)
goto exit;
}
n->addr = addr;
+ memcpy(&n->peer_id, peer_id, 16);
n->net = net;
n->capabilities = capabilities;
kref_init(&n->kref);
@@ -344,8 +372,8 @@ struct tipc_node *tipc_node_create(struct net *net, u32 addr, u16 capabilities)
n->signature = INVALID_NODE_SIG;
n->active_links[0] = INVALID_BEARER_ID;
n->active_links[1] = INVALID_BEARER_ID;
- if (!tipc_link_bc_create(net, tipc_own_addr(net), n->addr,
- U16_MAX,
+ if (!tipc_link_bc_create(net, tipc_own_addr(net),
+ addr, U16_MAX,
tipc_link_window(tipc_bc_sndlink(net)),
n->capabilities,
&n->bc_entry.inputq1,
@@ -735,8 +763,51 @@ bool tipc_node_is_up(struct net *net, u32 addr)
return retval;
}
-void tipc_node_check_dest(struct net *net, u32 onode,
- struct tipc_bearer *b,
+static u32 tipc_node_suggest_addr(struct net *net, u32 addr)
+{
+ struct tipc_node *n;
+
+ addr ^= tipc_net(net)->random;
+ while ((n = tipc_node_find(net, addr))) {
+ tipc_node_put(n);
+ addr++;
+ }
+ return addr;
+}
+
+/* tipc_node_try_addr(): Check if addr can be used by peer, suggest other if not
+ */
+u32 tipc_node_try_addr(struct net *net, u8 *id, u32 addr)
+{
+ struct tipc_net *tn = tipc_net(net);
+ struct tipc_node *n;
+
+ /* Suggest new address if some other peer is using this one */
+ n = tipc_node_find(net, addr);
+ if (n) {
+ if (!memcmp(n->peer_id, id, NODE_ID_LEN))
+ addr = 0;
+ tipc_node_put(n);
+ if (!addr)
+ return 0;
+ return tipc_node_suggest_addr(net, addr);
+ }
+
+ /* Suggest previously used address if peer is known */
+ n = tipc_node_find_by_id(net, id);
+ if (n) {
+ addr = n->addr;
+ tipc_node_put(n);
+ }
+ /* Even this node may be in trial phase */
+ if (tn->trial_addr == addr)
+ return tipc_node_suggest_addr(net, addr);
+
+ return addr;
+}
+
+void tipc_node_check_dest(struct net *net, u32 addr,
+ u8 *peer_id, struct tipc_bearer *b,
u16 capabilities, u32 signature,
struct tipc_media_addr *maddr,
bool *respond, bool *dupl_addr)
@@ -755,7 +826,7 @@ void tipc_node_check_dest(struct net *net, u32 onode,
*dupl_addr = false;
*respond = false;
- n = tipc_node_create(net, onode, capabilities);
+ n = tipc_node_create(net, addr, peer_id, capabilities);
if (!n)
return;
@@ -840,7 +911,7 @@ void tipc_node_check_dest(struct net *net, u32 onode,
if (!tipc_link_create(net, if_name, b->identity, b->tolerance,
b->net_plane, b->mtu, b->priority,
b->window, mod(tipc_net(net)->random),
- tipc_own_addr(net), onode,
+ tipc_own_addr(net), addr, peer_id,
n->capabilities,
tipc_bc_sndlink(n->net), n->bc_entry.link,
&le->inputq,
diff --git a/net/tipc/node.h b/net/tipc/node.h
index e06faf4..f24b835 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -60,7 +60,8 @@ enum {
#define INVALID_BEARER_ID -1
void tipc_node_stop(struct net *net);
-void tipc_node_check_dest(struct net *net, u32 onode,
+u32 tipc_node_try_addr(struct net *net, u8 *id, u32 addr);
+void tipc_node_check_dest(struct net *net, u32 onode, u8 *peer_id128,
struct tipc_bearer *bearer,
u16 capabilities, u32 signature,
struct tipc_media_addr *maddr,
--
2.1.4
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox