1 #include <linux/module.h>
2 #include <linux/if_ether.h>
4 #include "../ipn_hash.h"
7 MODULE_AUTHOR("VIEW-OS TEAM");
8 MODULE_DESCRIPTION("VDE SWITCH Kernel Module");
10 static struct kmem_cache
*kvde_net_cache
;
11 #define IS_BROADCAST(addr) ((addr[0] & 1) == 1)
13 static int ipn_kvde_switch_newport(struct ipn_node
*newport
) {
14 struct ipn_network
*ipnn
=newport
->ipn
;
16 for (i
=0;i
<ipnn
->maxports
;i
++) {
17 if (ipnn
->connport
[i
] == NULL
)
23 static int ipn_kvde_switch_handlemsg(struct ipn_node
*from
,
24 struct msgpool_item
*msgitem
,
26 struct ipn_network
*ipnn
=from
->ipn
;
27 struct ipn_hash
*vdeh
=(struct ipn_hash
*)ipnn
->proto_private
;
29 struct ethhdr
*ehdr
=(struct ethhdr
*)msgitem
->data
;
30 if (msgitem
->len
< sizeof(struct ethhdr
))
32 if (!IS_BROADCAST(ehdr
->h_source
))
33 ipn_hash_add(vdeh
,(u16
*)&ehdr
->h_source
,0,from
->portno
);
34 if (IS_BROADCAST(ehdr
->h_dest
) ||
35 (port
= ipn_hash_find(vdeh
,(u16
*)&ehdr
->h_dest
,0)) < 0) {
36 /*printk("SWITCH FROM %d -> BROADCAST\n",from->portno);*/
37 for (port
=0; port
<ipnn
->maxports
; port
++)
38 if (ipnn
->connport
[port
] && ipnn
->connport
[port
] != from
)
39 ipn_proto_sendmsg(ipnn
->connport
[port
],msgitem
,depth
);
41 /*printk("SWITCH FROM %d -> %d\n",from->portno,port);*/
42 ipn_proto_sendmsg(ipnn
->connport
[port
],msgitem
,depth
);
47 static void ipn_kvde_switch_delport(struct ipn_node
*oldport
) {
48 struct ipn_network
*ipnn
=oldport
->ipn
;
49 struct ipn_hash
*vdeh
=(struct ipn_hash
*)ipnn
->proto_private
;
50 ipn_hash_flush_port(vdeh
,oldport
->portno
);
53 static int ipn_kvde_switch_newnet(struct ipn_network
*newnet
) {
54 struct ipn_hash
*vdeh
=kmem_cache_alloc(kvde_net_cache
,GFP_KERNEL
);
57 if (!try_module_get(THIS_MODULE
))
59 newnet
->proto_private
=vdeh
;
60 ipn_hash_new(vdeh
,256,30);
64 static void ipn_kvde_switch_delnet(struct ipn_network
*oldnet
) {
65 struct ipn_hash
*vdeh
=(struct ipn_hash
*) oldnet
->proto_private
;
67 kmem_cache_free(kvde_net_cache
,vdeh
);
68 module_put(THIS_MODULE
);
71 static int ipn_kvde_switch_setsockopt(struct ipn_node
*port
,int optname
,
72 char __user
*optval
, int optlen
) {return -EOPNOTSUPP
;}
73 static int ipn_kvde_switch_getsockopt(struct ipn_node
*port
,int optname
,
74 char __user
*optval
, int *optlen
) {return -EOPNOTSUPP
;}
75 static int ipn_kvde_switch_ioctl(struct ipn_node
*port
,unsigned int request
,
76 unsigned long arg
) {return -EOPNOTSUPP
;}
78 /* static void ipn_kvde_switch_postnewport(struct ipn_node *newport) {} */
79 /* static void ipn_kvde_switch_predelport(struct ipn_node *oldport) {} */
80 static struct ipn_protocol vde_switch_proto
={
81 .ipn_p_newport
=ipn_kvde_switch_newport
,
82 .ipn_p_handlemsg
=ipn_kvde_switch_handlemsg
,
83 .ipn_p_delport
=ipn_kvde_switch_delport
,
84 /*.ipn_p_postnewport=ipn_kvde_switch_postnewport,*/
85 /*.ipn_p_predelport=ipn_kvde_switch_predelport,*/
86 .ipn_p_newnet
=ipn_kvde_switch_newnet
,
87 .ipn_p_delnet
=ipn_kvde_switch_delnet
,
88 .ipn_p_setsockopt
=ipn_kvde_switch_setsockopt
,
89 .ipn_p_getsockopt
=ipn_kvde_switch_getsockopt
,
90 .ipn_p_ioctl
=ipn_kvde_switch_ioctl
94 static int kvde_switch_init(void)
97 kvde_net_cache
=kmem_cache_create("kvde_net",sizeof(struct ipn_hash
),0,0,NULL
,NULL
);
98 if (!kvde_net_cache
) {
102 rc
=ipn_proto_register(IPN_VDESWITCH
,&vde_switch_proto
);
107 static void kvde_switch_exit(void)
109 ipn_proto_deregister(IPN_VDESWITCH
);
111 kmem_cache_destroy(kvde_net_cache
);
114 module_init(kvde_switch_init
);
115 module_exit(kvde_switch_exit
);