netmap: add extra interface on bridge
upyzl
zj262144 at gmail.com
Tue Nov 4 07:07:00 UTC 2014
Very useful!
thx very much
2014-11-04 3:34 GMT+08:00 Luigi Rizzo <rizzo at iet.unipi.it>:
>
>
> On Monday, November 3, 2014, upyzl <zj262144 at 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 at freebsd.org mailing list
>> http://lists.freebsd.org/mailman/listinfo/freebsd-net
>> To unsubscribe, send any mail to "freebsd-net-unsubscribe at freebsd.org"
>>
>
>
> --
> -----------------------------------------+-------------------------------
> Prof. Luigi RIZZO, rizzo at 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)
> -----------------------------------------+-------------------------------
>
>
More information about the freebsd-net
mailing list