Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 4 Nov 2014 15:06:58 +0800
From:      upyzl <zj262144@gmail.com>
To:        Luigi Rizzo <rizzo@iet.unipi.it>
Cc:        "freebsd-net@freebsd.org" <freebsd-net@freebsd.org>
Subject:   Re: netmap: add extra interface on bridge
Message-ID:  <CAMijcFFcRRRGpW5FwwJ9szxFC8r3HkrP2bB5AyK4TNCbqH_jDg@mail.gmail.com>
In-Reply-To: <CA%2BhQ2%2BgvSmtcOjnNi0sPyyaEFwTx0khhesv4ArG1pvoZPz6Enw@mail.gmail.com>
References:  <CAMijcFFue58ORCFWZ9x5G3fKJ%2BXYRXPVWw59T5Udw1X0hR2Grg@mail.gmail.com> <CA%2BhQ2%2BgvSmtcOjnNi0sPyyaEFwTx0khhesv4ArG1pvoZPz6Enw@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
Very useful!

thx very much

2014-11-04 3:34 GMT+08:00 Luigi Rizzo <rizzo@iet.unipi.it>:

>
>
> On Monday, November 3, 2014, upyzl <zj262144@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-unsubscribe@freebsd.org"
>>
>
>
> --
> -----------------------------------------+-------------------------------
>  Prof. Luigi RIZZO, rizzo@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)
> -----------------------------------------+-------------------------------
>
>



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAMijcFFcRRRGpW5FwwJ9szxFC8r3HkrP2bB5AyK4TNCbqH_jDg>