RFC: TIPC API, bind to two networks
Subsystems (4)
I'd like some feedback on a change to TIPC that I plan to submit to netdev/kernel.org. At this stage, I'm interested in what people think about using the protocol parameter of the socket interface to select a TIPC stack for the socket. My co-worker, Chris Friesen, has suggested that it would be more conventional to extend the TIPC sockaddr to select the appropriate network in calls to sendto() or bind(). I prefer socket(,,protocol) approach.
Some background:
We use TIPC in an ATCA chassis (Advanced Telecommunications Computing Architecture). An ATCA chassis may have two networks commonly called base and data (outside of the ATCA world base is called control).
Users want to be able to create a TIPC socket that is bound to one network OR the other. The intention is that these networks should be isolated as much as possible.
The attached patch accomplishes this by using the protocol parameter of the socket() syscall. A user can specify the TIPC stack to which the socket should be attached as follows:
int socket(int domain, int type, int protocol);
fd = socket(AF_TIPC, SOCK_SEQPACKET, 1);In the unpatched TIPC code the protocol was required to be zero. This requires that the user know the network topology or that the system designer provide an API (get_base_netid(), get_data_netid()).
The patch is for tipc-1.5.12 which you can get from tipc.sf.net. We're way back on linux-2.6.14 - gotta love the embedded world!
In terms of implementation,
the basic idea of the patch is to introduce a layer in the TIPC code around socket creation and tipc netlink messages. This layer lets TIPC stack code register callback functions and then dispatches socket() and netlink calls to the appropriate TIPC stack.
For example usage, please see:
<http://sourceforge.net/mailarchive/message.php?msg_name=476839F3.8070203%40nortel.com>
One note for those who might not read the link above.... I create two modules: tipc.ko and tipcstack.ko these are ~98% identical with certain bits of functionality, like registering AF_TIPC, disabled. This means that we have the same bits of code loaded twice but that's a feature not a bug! It means that the control and data networks are even more independent so you could update one but not the other or you could use system tap on one but not the other.
diffstat:
Makefile | 15 +++- include/net/tipc/tipc.h | 11 ++- net/tipc/core.c | 157 +++++++++++++++++++++++------------------------- net/tipc/core.h | 25 +++++++ net/tipc/handler.c | 17 +++-- net/tipc/netlink.c | 21 +++++- net/tipc/socket.c | 55 ++++++++++++---- net/tipc/vtipc.c | 154 +++++++++++++++++++++++++++++++++++++++++++++++ net/tipc/vtipc.h | 48 ++++++++++++++ tools/tipc-config.c | 29 ++++++--
Even though I *don't* want the attached patch to be integrated into the kernel (yet), I'm still going to include:
because it's taken such a long time to get Nortel to bless official kernel participation!
// Randy
include/net/tipc/tipc.h +9 -2
@@ -71,7 +71,6 @@__u32 lower;__u32 upper; }; -static inline __u32 tipc_addr (unsigned int zone,unsigned int cluster,unsigned int node)
@@ -213,13 +212,21 @@/* * TIPC-specific socket option values */ -#define SOL_TIPC 50/* TIPC socket option level */ +#define TIPC_IMPORTANCE 127/* Default: TIPC_LOW_IMPORTANCE */ #define TIPC_SRC_DROPPABLE 128/* Default: 0 (resend congested msg) */ #define TIPC_DEST_DROPPABLE 129/* Default: based on socket type */ #define TIPC_CONN_TIMEOUT 130/* Default: 8000 (ms) */ +#define TIPC_STACK_0 0/* Default TIPC stack */ +#define TIPC_STACK_1 1/* 1st TIPC stack */ +#define TIPC_STACK_2 2/* 2nd TIPC stack */ +#define TIPC_STACK_3 3/* 3rd TIPC stack */ +#define TIPC_STACK_4 4/* 4th TIPC stack */ +#define TIPC_STACK_5 5/* 5th TIPC stack */ +#define TIPC_STACK_6 6/* 6th TIPC stack */ +#define TIPC_STACK_7 7/* 7th TIPC stack */ #ifdef __KERNEL__
Makefile +12 -3
@@ -3,8 +3,6 @@ # SHELL = /bin/bash - - ifdef KERNELDIR KINCLUDE = ${KERNELDIR}/include
@@ -22,8 +20,19 @@ -DCONFIG_TIPC_DEBUG obj-m += tipc.o +obj-m += tipcstack.o + +tipc-objs += net/tipc/addr.o net/tipc/bcast.o net/tipc/discover.o \ + net/tipc/cluster.o net/tipc/dbg.o net/tipc/link.o \ + net/tipc/config.o net/tipc/bearer.o net/tipc/msg.o \ + net/tipc/name_distr.o net/tipc/subscr.o \ + net/tipc/name_table.o net/tipc/net.o net/tipc/node.o \ + net/tipc/node_subscr.o net/tipc/port.o \ + net/tipc/ref.o net/tipc/user_reg.o net/tipc/zone.o \ + net/tipc/core.o net/tipc/handler.o net/tipc/netlink.o \ + net/tipc/socket.o net/tipc/eth_media.o net/tipc/vtipc.o -tipc-objs += net/tipc/addr.o net/tipc/bcast.o net/tipc/discover.o \ +tipcstack-objs += net/tipc/addr.o net/tipc/bcast.o net/tipc/discover.o \ net/tipc/cluster.o net/tipc/dbg.o net/tipc/link.o \ net/tipc/config.o net/tipc/bearer.o net/tipc/msg.o \ net/tipc/name_distr.o net/tipc/subscr.o \
net/tipc/core.c +78 -79
222 lines not on this page · raw message
net/tipc/core.h +23 -2
@@ -66,6 +66,16 @@#define assert (i) BUG_ON(!(i)) +/* +* The role specifies if the loaded module is tipc core, +* stack or both. +*/ +#define TIPC_ROLE_FULL 0 +#define TIPC_ROLE_CORE 1 +#define TIPC_ROLE_STACK 2 + +#define MAX_TIPC_STACKS 8 +struct tipc_msg ;extern struct print_buf *CONS , *LOG ;extern struct print_buf *TEE (struct print_buf *,struct print_buf *);
@@ -174,12 +184,23 @@extern atomic_t tipc_user_count; +struct net_vtipc_proto { +int stack_number; +u32 *tipc_own_addr_p; +int (*registration)(struct socket *sock,int protocol); +struct sk_buff *(*netlink_registration)(__u32 orig_node,__u16 cmd, +const void *req_tlv_area, +int req_tlv_space, +int headroom); +struct module *owner; +}; +/* * Routines available to privileged subsystems */ -extern int start_core (void ); -extern void stop_core (void ); +extern int start_core (int role,int stack_id); +extern void stop_core (int role,int stack_id);extern int start_net (void );extern void stop_net (void );
net/tipc/handler.c +12 -5
@@ -144,11 +144,18 @@spin_unlock_bh (&qitem_lock); } -int handler_start (void ) +int handler_start (int role,int stack_id) { - tipc_queue_item_cache = -kmem_cache_create ("tipc_queue_items" ,sizeof (struct queue_item ), -0 ,SLAB_HWCACHE_ALIGN ,NULL ,NULL ); +#define tipc_qi_length 20 +static char tipc_queue_items[tipc_qi_length] = {0 }; +/*The stack_id should be 2 digits*/ +if (stack_id >99 ) { +err ("stack id out of range 0 - 99.\n" ); +return -ENOMEM ; + } +snprintf (tipc_queue_items, tipc_qi_length,"tipc_queue_items_%02d" , stack_id); + tipc_queue_item_cache =kmem_cache_create (tipc_queue_items, +sizeof (struct queue_item ),0 ,SLAB_HWCACHE_ALIGN ,NULL ,NULL );if (!tipc_queue_item_cache)return -ENOMEM ;
@@ -158,7 +165,7 @@return 0 ; } -void handler_stop (void ) +void handler_stop (int role,int stack_id) {struct list_head *l, *n;struct queue_item *item;
net/tipc/netlink.c +19 -2
@@ -60,6 +60,7 @@#include "core.h" #include "config.h" +extern struct net_vtipc_proto *tipc_families[MAX_TIPC_STACKS ];#ifdef ENABLE_NETLINK_GENERIC /* * NETLINK_GENERIC
@@ -158,13 +159,29 @@if ((req_nlh->nlmsg_type &0xC000 ) && (!capable (CAP_NET_ADMIN ))) rep_buf =cfg_reply_error_string (TIPC_CFG_NOT_NET_ADMIN ); -else +/* +* RKR: TODO : req_nlh->nlmsg_flags > 0 +* Not Sure if we really need to handle stack zero as a special case? +* Even if we are running in the original tipc mode, we could introduce +* the additional registration and callback layer that we use for vtipc stacks. +* Need to modify this. +*/ +if (req_nlh->nlmsg_flags >0 ) { +if (tipc_families[req_nlh->nlmsg_flags]) { + rep_buf = (*(tipc_families[req_nlh->nlmsg_flags]->netlink_registration)) + ((*tipc_families[req_nlh->nlmsg_flags]->tipc_own_addr_p), + req_nlh->nlmsg_type,NLMSG_DATA (req_nlh), +NLMSG_PAYLOAD (req_nlh,0 ), hdr_space); + }else { + rep_buf =cfg_reply_error_string (TIPC_CFG_INVALID_VALUE ); + } + }else { rep_buf =cfg_do_cmd (tipc_own_addr, req_nlh->nlmsg_type,NLMSG_DATA (req_nlh),NLMSG_PAYLOAD (req_nlh,0 ), hdr_space); - + }if (rep_buf) {skb_push (rep_buf, hdr_space); rep_nlh = (struct nlmsghdr *)rep_buf->data;
net/tipc/socket.c +42 -13
113 lines not on this page · raw message
net/tipc/vtipc.c +154 -0
154 lines not on this page · raw message
net/tipc/vtipc.h +48 -0
48 lines not on this page · raw message
tools/tipc-config.c +22 -7
@@ -84,6 +84,7 @@/* local variables */ static int verbose =0 ; +static int stack_id =0 ;static int interactive =0 ;static __u32 dest =0 ;static __u32 tlv_area[MAX_TLVS_SPACE /sizeof (__u32)];
@@ -134,13 +135,13 @@return val; } -static __u32 own_node (void ) +static __u32 own_node (int stack_id) {struct sockaddr_tipc addr;socklen_t sz =sizeof (addr);int sd; - sd =socket (AF_TIPC ,SOCK_RDM ,0 ); + sd =socket (AF_TIPC ,SOCK_RDM , stack_id);if (sd <0 )err (1 ,"TIPC module not installed\n" );if (getsockname (sd, (struct sockaddr *)&addr, &sz) <0 )
@@ -164,7 +165,7 @@ {static char addr_area[30 ]; -if (dest ==own_node ()) +if (dest ==own_node (stack_id))return "" ;sprintf (addr_area," for node %s" ,addr2str (dest));return addr_area;
@@ -367,7 +368,7 @@ req.n.nlmsg_len =NLMSG_LENGTH (req_tlv_space); req.n.nlmsg_type = cmd; - req.n.nlmsg_flags =0 ; + req.n.nlmsg_flags = stack_id; req.n.nlmsg_seq =0 ; req.n.nlmsg_pid =getpid ();if (req_tlv_space)
@@ -486,7 +487,7 @@ {int rep_len; -if (dest ==own_node ()) +if (dest ==own_node (stack_id)) rep_len =do_command_netlink (cmd, req_tlv, req_tlv_space, rep_tlv, rep_tlv_space);else
@@ -791,6 +792,17 @@cprintf ("Link %s statistics reset\n" , link_name); } +static void set_stack_id (char *args) +{ +if (!*args) { + stack_id =0 ; +printf ("No stack id is provided so resetting to default value of 0" ); + }else { + stack_id =atoi (args); + dest =own_node (stack_id); +printf ("The stack id is %d\n" , stack_id); + } +}static void show_name_table (char *args) {int tlv_space;
@@ -1436,6 +1448,7 @@ " where <depth> = types|names|ports|all\n"#if 1 " -p Get port info\n" +" -s =<stack_id> Configure a virtulal tipc stack based on stack number\n"#else " -p [=all|bound|connected|<port>] Get port info\n" " -ps =<port> Get port statistics\n"
@@ -1518,6 +1531,7 @@ {"max_nodes", 2, 0, OPT_BASE + 30}, {"max_slaves", 2, 0, OPT_BASE + 31}, {"log", 2, 0, OPT_BASE + 32}, + {"s", 1, 0, OPT_BASE + 33}, {0, 0, 0, 0} };
@@ -1555,6 +1569,7 @@ set_max_nodes, set_max_slaves, set_log_size, + set_stack_id, NULL };
@@ -1572,8 +1587,8 @@if (argc ==1 )err (1 , usage); - - dest =own_node (); + stack_id =0 ; + dest =own_node (stack_id); cno =0 ;while ((c =getopt_long_only (argc, argv,"" , options,NULL )) !=EOF ) {
-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace
_______________________________________________
tipc-discussion mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tipc-discussion