Commit 22700706 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'sctp-vrf'



Xin Long says:

====================
sctp: support vrf processing

This patchset adds the VRF processing in SCTP. Simliar to TCP/UDP,
it includes socket bind and socket/association lookup changes.

For socket bind change, it allows sockets to bind to a VRF device
and allows multiple sockets with the same IP and PORT to bind to
different interfaces in patch 1-3.

For socket/association lookup change, it adds dif and sdif check
in both asoc and ep lookup in patch 4 and 5, and when binding to
nodev, users can decide if accept the packets received from one
l3mdev by setup a sysctl option in patch 6.

Note with VRF support, in a netns, an association will be decided
by src ip + src port + dst ip + dst port + bound_dev_if, and it's
possible for ss to have:

  State       Local Address:Port      Peer Address:Port
   ESTAB     192.168.1.2%vrf-s1:1234
   `- ESTAB   192.168.1.2%veth1:1234   192.168.1.1:1234
   ESTAB     192.168.1.2%vrf-s2:1234
   `- ESTAB   192.168.1.2%veth2:1234   192.168.1.1:1234

See the selftest in patch 7 for more usage.

Also, thanks Carlo for testing this patch series on their use.

v1->v2:
  - In Patch 5, move sctp_sk_bound_dev_eq() definition to net/sctp/
    input.c to avoid a build error when IP_SCTP is disabled, as Paolo
    suggested.
  - In Patch 7, avoid one sleep by disabling the IPv6 dad, and remove
    another sleep by using ss to check if the server's ready, and also
    delete two unncessary sleeps in sctp_hello.c, as Paolo suggested.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 0b6ffefb a61bd7b9
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -3127,6 +3127,15 @@ ecn_enable - BOOLEAN

        Default: 1

l3mdev_accept - BOOLEAN
	Enabling this option allows a "global" bound socket to work
	across L3 master domains (e.g., VRFs) with packets capable of
	being received regardless of the L3 domain in which they
	originated. Only valid when the kernel was compiled with
	CONFIG_NET_L3_MASTER_DEV.

	Default: 1 (enabled)


``/proc/sys/net/core/*``
========================
+4 −0
Original line number Diff line number Diff line
@@ -175,6 +175,10 @@ struct netns_sctp {

	/* Threshold for autoclose timeout, in seconds. */
	unsigned long max_autoclose;

#ifdef CONFIG_NET_L3_MASTER_DEV
	int l3mdev_accept;
#endif
};

#endif /* __NETNS_SCTP_H__ */
+4 −2
Original line number Diff line number Diff line
@@ -109,7 +109,7 @@ struct sctp_transport *sctp_transport_get_idx(struct net *net,
			struct rhashtable_iter *iter, int pos);
int sctp_transport_lookup_process(sctp_callback_t cb, struct net *net,
				  const union sctp_addr *laddr,
				  const union sctp_addr *paddr, void *p);
				  const union sctp_addr *paddr, void *p, int dif);
int sctp_transport_traverse_process(sctp_callback_t cb, sctp_callback_t cb_done,
				    struct net *net, int *pos, void *p);
int sctp_for_each_endpoint(int (*cb)(struct sctp_endpoint *, void *), void *p);
@@ -157,10 +157,12 @@ void sctp_unhash_transport(struct sctp_transport *t);
struct sctp_transport *sctp_addrs_lookup_transport(
				struct net *net,
				const union sctp_addr *laddr,
				const union sctp_addr *paddr);
				const union sctp_addr *paddr,
				int dif, int sdif);
struct sctp_transport *sctp_epaddr_lookup_transport(
				const struct sctp_endpoint *ep,
				const union sctp_addr *paddr);
bool sctp_sk_bound_dev_eq(struct net *net, int bound_dev_if, int dif, int sdif);

/*
 * sctp/proc.c
+6 −3
Original line number Diff line number Diff line
@@ -477,6 +477,7 @@ struct sctp_af {
	int		(*available)	(union sctp_addr *,
					 struct sctp_sock *);
	int		(*skb_iif)	(const struct sk_buff *sk);
	int		(*skb_sdif)(const struct sk_buff *sk);
	int		(*is_ce)	(const struct sk_buff *sk);
	void		(*seq_dump_addr)(struct seq_file *seq,
					 union sctp_addr *addr);
@@ -1378,10 +1379,12 @@ struct sctp_association *sctp_endpoint_lookup_assoc(
	struct sctp_transport **);
bool sctp_endpoint_is_peeled_off(struct sctp_endpoint *ep,
				 const union sctp_addr *paddr);
struct sctp_endpoint *sctp_endpoint_is_match(struct sctp_endpoint *,
					struct net *, const union sctp_addr *);
struct sctp_endpoint *sctp_endpoint_is_match(struct sctp_endpoint *ep,
					     struct net *net,
					     const union sctp_addr *laddr,
					     int dif, int sdif);
bool sctp_has_association(struct net *net, const union sctp_addr *laddr,
			  const union sctp_addr *paddr);
			  const union sctp_addr *paddr, int dif, int sdif);

int sctp_verify_init(struct net *net, const struct sctp_endpoint *ep,
		     const struct sctp_association *asoc,
+2 −1
Original line number Diff line number Diff line
@@ -426,6 +426,7 @@ static int sctp_diag_dump_one(struct netlink_callback *cb,
	struct net *net = sock_net(skb->sk);
	const struct nlmsghdr *nlh = cb->nlh;
	union sctp_addr laddr, paddr;
	int dif = req->id.idiag_if;
	struct sctp_comm_param commp = {
		.skb = skb,
		.r = req,
@@ -454,7 +455,7 @@ static int sctp_diag_dump_one(struct netlink_callback *cb,
	}

	return sctp_transport_lookup_process(sctp_sock_dump_one,
					     net, &laddr, &paddr, &commp);
					     net, &laddr, &paddr, &commp, dif);
}

static void sctp_diag_dump(struct sk_buff *skb, struct netlink_callback *cb,
Loading