Very useful! thx very much
2014-11-04 3:34 GMT+08:00 Luigi Rizzo <ri...@iet.unipi.it>: > > > 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 mailing list >> http://lists.freebsd.org/mailman/listinfo/freebsd-net >> To unsubscribe, send any mail to "freebsd-net-unsubscr...@freebsd.org" >> > > > -- > -----------------------------------------+------------------------------- > 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"