From owner-freebsd-net@FreeBSD.ORG Tue Nov 4 07:07:00 2014 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 2FE62368 for ; Tue, 4 Nov 2014 07:07:00 +0000 (UTC) Received: from mail-ob0-x231.google.com (mail-ob0-x231.google.com [IPv6:2607:f8b0:4003:c01::231]) (using TLSv1 with cipher ECDHE-RSA-RC4-SHA (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority G2" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id EBC16C01 for ; Tue, 4 Nov 2014 07:06:59 +0000 (UTC) Received: by mail-ob0-f177.google.com with SMTP id m8so9957116obr.22 for ; Mon, 03 Nov 2014 23:06:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=2jzWrFYnU4AB2RROj4zrYH+i8SyorGijFISbXN7tQXg=; b=Ohuc7gF8aIdo76vGSXw/6wVzMvW/oBpXETTzpVm12bbpMxSGA+aUofctv+4JDcDk5L OsRFz0YxNMH8kjrd3W43pTV9xDhkDMGjTUM6n5/42D51Z1FsZ/d1B3dbQ5T1fYuepxFP qVwms1MWbteh6w2ehmpMW6KefifRu0I61gp8A/uX+hb3RUbhFJWUvoghWltYxk1CWRke 9ReDWUMEutKrA/+915pbTWiQ92DvIhW9UNHzObKmBfmRLuj5nLsKxjKK0UZYivI8a6KZ ZPaZ8t2Om31ok7o2LPwFVxjfyBRF9gZlTmycSxnQUWWJyN/iAXa4hDM50kB0BgubQEmA T9Zg== MIME-Version: 1.0 X-Received: by 10.182.92.234 with SMTP id cp10mr663921obb.53.1415084819044; Mon, 03 Nov 2014 23:06:59 -0800 (PST) Received: by 10.76.167.202 with HTTP; Mon, 3 Nov 2014 23:06:58 -0800 (PST) In-Reply-To: References: Date: Tue, 4 Nov 2014 15:06:58 +0800 Message-ID: Subject: Re: netmap: add extra interface on bridge From: upyzl To: Luigi Rizzo Content-Type: text/plain; charset=UTF-8 X-Content-Filtered-By: Mailman/MimeDel 2.1.18-1 Cc: "freebsd-net@freebsd.org" X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 04 Nov 2014 07:07:00 -0000 Very useful! thx very much 2014-11-04 3:34 GMT+08:00 Luigi Rizzo : > > > On Monday, November 3, 2014, upyzl 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) > -----------------------------------------+------------------------------- > >