On Monday, November 3, 2014, upyzl <zj262...@gmail.com> wrote: > Hi there, > > I'm study on developing a simple openflow-based datapath module > > I know and tried successfully by "bridge -i em0 -i em1" > > Now I need bridge em0 em1 em2, but I find using vale-ctl is very difficult > for me, as I need develop extract, match packets (packets from IN_PORT) and > do actions from flow table (for simple, the flow table is static).
You are much batter off rewriting the whole thing yoirself. bridge.c is hardwired for transparent interconnection of two interfaces, so the patches you show below cannot possibly work. Here is a suggestion. Try to design (pen and paper) a simple handler that grabs packets from one interface, classifies them using your custom floe table and queues to the various output interfaces. Write a second handler that takes packets from an output queue and pushes them to a port. Ignore performance, for simplicity; thingd are already hard enough. Ignore the fact you are using netmap, that is just a detail, you can design your pseudo code as something that reads one packet at a time and writes one packet at a time. In the process, define what is your policy for dealing with a full output queue, also consider the broadcast case (you either drop, or block but with a timeout to avoid stalling the world because of a single port being down). Then you can write your event loop registering all input fds that are not blocked (see previous point), all output fds that have traffic queued, a timeout handler. This will be single threaded do you do not have to worry about locking. Once this works you can look at performance. For that, there is a ton of solutions (heavily commented) you can find in netmap_vale.c part of the netmap sources. Cheers Luigi > > I try like this, but only em0 & em1 are connect, without em2... > > --- "a/bridge.c" > +++ "b/bridge.c" > @@ -162,11 +162,11 @@ usage(void) > int > main(int argc, char **argv) > { > - struct pollfd pollfd[2]; > + struct pollfd pollfd[3]; > int i, ch; > u_int burst = 1024, wait_link = 4; > - struct my_ring me[2]; > - char *ifa = NULL, *ifb = NULL; > + struct my_ring me[3]; > + char *ifa = NULL, *ifb = NULL, *ifc = NULL; > > fprintf(stderr, "%s %s built %s %s\n", > argv[0], version, __DATE__, __TIME__); > @@ -187,6 +187,8 @@ main(int argc, char **argv) > ifa = optarg; > else if (ifb == NULL) > ifb = optarg; > + else if (ifc == NULL) > + ifc = optarg; > else > D("%s ignored, already have 2 interfaces", > optarg); > @@ -209,6 +211,8 @@ main(int argc, char **argv) > if (argc > 2) > ifb = argv[2]; > if (argc > 3) > + ifc = argv[3]; > + if (argc > 4) > burst = atoi(argv[3]); > if (!ifb) > ifb = ifa; > @@ -227,6 +231,7 @@ main(int argc, char **argv) > /* setup netmap interface #1. */ > me[0].ifname = ifa; > me[1].ifname = ifb; > + me[2].ifname = ifc; > if (!strcmp(ifa, ifb)) { > D("same interface, endpoint 0 goes to host"); > i = NETMAP_SW_RING; > @@ -236,13 +241,15 @@ main(int argc, char **argv) > } > if (netmap_open(me, i, 1)) > return (1); > - me[1].mem = me[0].mem; /* copy the pointer, so only one mmap */ > + me[2].mem = me[1].mem = me[0].mem; /* copy the pointer, so only one > mmap */ > if (netmap_open(me+1, 0, 1)) > return (1); > + if (netmap_open(me+2, 0, 1)) > + return (1); > > /* setup poll(2) variables. */ > memset(pollfd, 0, sizeof(pollfd)); > - for (i = 0; i < 2; i++) { > + for (i = 0; i < 3; i++) { > pollfd[i].fd = me[i].fd; > pollfd[i].events = (POLLIN); > } > @@ -256,20 +263,31 @@ main(int argc, char **argv) > /* main loop */ > signal(SIGINT, sigint_h); > while (!do_abort) { > - int n0, n1, ret; > - pollfd[0].events = pollfd[1].events = 0; > - pollfd[0].revents = pollfd[1].revents = 0; > + int n0, n1, n2, ret; > + pollfd[0].events = pollfd[1].events = pollfd[2].events = 0; > + pollfd[0].revents = pollfd[1].revents = pollfd[2].revents = 0; > n0 = pkt_queued(me, 0); > n1 = pkt_queued(me + 1, 0); > - if (n0) > + n2 = pkt_queued(me + 2, 0); > + if (n0) { > pollfd[1].events |= POLLOUT; > + pollfd[2].events |= POLLOUT; > + } > else > pollfd[0].events |= POLLIN; > - if (n1) > + if (n1) { > pollfd[0].events |= POLLOUT; > + pollfd[2].events |= POLLOUT; > + } > else > pollfd[1].events |= POLLIN; > - ret = poll(pollfd, 2, 2500); > + if (n2) { > + pollfd[0].events |= POLLOUT; > + pollfd[1].events |= POLLOUT; > + } > + else > + pollfd[2].events |= POLLIN; > + ret = poll(pollfd, 3, 2500); > if (ret <= 0 || verbose) > D("poll %s [0] ev %x %x rx %d@%d tx %d," > " [1] ev %x %x rx %d@%d tx %d", > @@ -297,16 +315,25 @@ main(int argc, char **argv) > } > if (pollfd[0].revents & POLLOUT) { > move(me + 1, me, burst); > + move(me + 2, me, burst); > // XXX we don't need the ioctl */ > // ioctl(me[0].fd, NIOCTXSYNC, NULL); > } > if (pollfd[1].revents & POLLOUT) { > move(me, me + 1, burst); > + move(me + 2, me + 1, burst); > // XXX we don't need the ioctl */ > // ioctl(me[1].fd, NIOCTXSYNC, NULL); > } > + if (pollfd[2].revents & POLLOUT) { > + move(me, me + 2, burst); > + move(me + 1, me + 2, burst); > + // XXX we don't need the ioctl */ > + // ioctl(me[2].fd, NIOCTXSYNC, NULL); > + } > } > D("exiting"); > + netmap_close(me + 2); > netmap_close(me + 1); > netmap_close(me + 0); > > > for last, use ioctl instead of move is failed either... > > any advices or relative documents for devel are welcome :) > > Regards > _______________________________________________ > freebsd-net@freebsd.org <javascript:;> mailing list > http://lists.freebsd.org/mailman/listinfo/freebsd-net > To unsubscribe, send any mail to "freebsd-net-unsubscr...@freebsd.org > <javascript:;>" > -- -----------------------------------------+------------------------------- Prof. Luigi RIZZO, ri...@iet.unipi.it . Dip. di Ing. dell'Informazione http://www.iet.unipi.it/~luigi/ . Universita` di Pisa TEL +39-050-2211611 . via Diotisalvi 2 Mobile +39-338-6809875 . 56122 PISA (Italy) -----------------------------------------+------------------------------- _______________________________________________ freebsd-net@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-net To unsubscribe, send any mail to "freebsd-net-unsubscr...@freebsd.org"