On Fri, Oct 24, 2014 at 9:43 AM, Ben Pfaff <b...@nicira.com> wrote:
> On Thu, Oct 16, 2014 at 11:38:20AM -0700, Pravin B Shelar wrote:
>> Following patch adds support for userspace tunneling. Tunneling
>> needs three more component first is routing table which is configured by
>> caching kernel routes and second is ARP cache which build automatically
>> by snooping arp. And third is tunnel protocol table which list all
>> listening protocols which is populated by vswitchd as tunnel ports
>> are added.
>>
>> Tunneling works as follows:
>> On packet receive vswitchd check if this packet is targeted to tunnel
>> port. If it is then vswitchd inserts tunnel pop action which pops
>> header and sends packet to tunnel port.
>> On packet xmit rather than generating Set tunnel action it generate
>> tunnel push action which has tunnel header data. datapath can use
>> tunnel-push action data to generate header for each packet and
>> forward this packet to output port. Since tunnel-push action
>> contains most of packet header it need to lookup routing table and
>> arp table to build this action.
>>
>> Signed-off-by: Pravin B Shelar <pshe...@nicira.com>
>
> I think that struct ovs_action_push_tnl is meant to be userspace-only so
> far.  In openvswitch.h, should the struct definition itself be enclosed
> in #ifndef __KERNEL__...#endif?
>
> (But I find myself wondering whether we should have a userspace-only
> extension mechanism for openvswitch.h.)
>

I will give a shot. Let me know if you already have idea.

>> +static int
>> +push_tunnel_action(const struct dp_netdev *dp,
>> +                   const struct nlattr *attr,
>> +                   struct dpif_packet **packets, int cnt)
>> +{
>> +    struct dp_netdev_port *tun_port;
>> +    struct ovs_action_push_tnl *data;
>> +
>> +    data = (struct ovs_action_push_tnl *) nl_attr_get(attr);
>
> The cast above shouldn't really be necessary, at least if you mark
> 'data' as const.
>
ok.

>> +static void
>> +dp_netdev_clone_pkt_batch(struct dpif_packet **tnl_pkt,
>> +                          struct dpif_packet **packets, int cnt)
>> +{
>> +    int i;
>> +
>> +    for (i = 0; i < cnt; i++) {
>> +        struct dpif_packet *inner_pkt;
>> +
>> +         inner_pkt = dpif_packet_clone(packets[i]);
>> +         tnl_pkt[i] = inner_pkt;
>
> The lines above are a long way to write "tnl_pkt[i] =
> dpif_packet_clone(packets[i]);".
>
ok.

>
>> +    }
>> +}
>> +
>>  static void
>>  dp_execute_cb(void *aux_, struct dpif_packet **packets, int cnt,
>>                const struct nlattr *a, bool may_steal)
>> @@ -2816,6 +2862,60 @@ dp_execute_cb(void *aux_, struct dpif_packet 
>> **packets, int cnt,
>>          }
>>          break;
>>
>> +    case OVS_ACTION_ATTR_TUNNEL_PUSH:
>> +        if (*depth < MAX_RECIRC_DEPTH) {
>> +            struct dpif_packet *tnl_pkt[NETDEV_MAX_RX_BATCH];
>> +            int err;
>> +
>> +            if (!may_steal) {
>> +                dp_netdev_clone_pkt_batch(tnl_pkt, packets, cnt);
>> +                packets = tnl_pkt;
>> +            }
>> +
>> +            err = push_tunnel_action(dp, a, packets, cnt);
>> +            if (err) {
>> +                dp_netdev_drop_packets(tnl_pkt, cnt, !may_steal);
>> +                break;
>> +            }
>> +
>> +            (*depth)++;
>> +            dp_netdev_input(pmd, packets, cnt);
>> +            (*depth)--;
>> +            return;
>> +        }
>> +        break;
>> +
>> +    case OVS_ACTION_ATTR_TUNNEL_POP:
>> +        if (*depth < MAX_RECIRC_DEPTH) {
>> +            odp_port_t portno = u32_to_odp(nl_attr_get_u32(a));
>> +
>> +            p = dp_netdev_lookup_port(dp, portno);
>> +            if (p) {
>> +                struct dpif_packet *tnl_pkt[NETDEV_MAX_RX_BATCH];
>> +                int err;
>> +
>> +                if (!may_steal) {
>> +                   dp_netdev_clone_pkt_batch(tnl_pkt, packets, cnt);
>> +                   packets = tnl_pkt;
>> +                }
>> +
>> +                err = netdev_pop_header(p->netdev, packets, cnt);
>> +                if (!err) {
>> +
>> +                    for (i = 0; i < cnt; i++) {
>> +                        packets[i]->md.in_port.odp_port = portno;
>> +                    }
>> +
>> +                    (*depth)++;
>> +                    dp_netdev_input(pmd, packets, cnt);
>> +                    (*depth)--;
>> +                    return;
>> +               }
>> +               dp_netdev_drop_packets(tnl_pkt, cnt, !may_steal);
>
> The OVS_ACTION_ATTR_TUNNEL_POP case here handles the success case inside
> an 'if' statement; the OVS_ACTION_ATTR_TUNNEL_PUSH handles the failure
> case inside an 'if' statement.  I think that either approach is fine but
> I'd find the code more straightforward if a consistent approach were used.
>
> We now have multiple cases of code that checks and increments the depth
> and calls dp_netdev_input() and reduces the depth.  I wonder whether we
> could encapsulate that in a neat helper function, or just put it into
> dp_netdev_input() itself.
>
ok.

> We usually put the return type and function name on separate lines in
> userspace:
>> +bool dpif_support_tnl_push_pop(const struct dpif *dpif)
>> +{
>> +   return !strcmp(dpif->dpif_class->type, "netdev") ||
>> +          !strcmp(dpif->dpif_class->type, "dummy");
>> +}
>
right.

> We usually give the header guard the same name as the header file (this
> is in a file named gre.h):
>> +#ifndef NETDEV_GRE_H
>> +#define NETDEV_GRE_H 1
>> +
> This header file doesn't require most of the headers below:
>> +#include <stddef.h>
>> +#include <stdint.h>
>> +#include "list.h"
>> +#include "packets.h"
>> +#include "util.h"
>> +#include "netdev-dpdk.h"
>
> We don't usually add extern "C" unless someone asks for them:
>> +#ifdef  __cplusplus
>> +extern "C" {
>> +#endif
>> +
>> +/* GRE protocol header */
>> +struct gre_base_hdr {
>> +    ovs_be16 flags;
>> +    ovs_be16 protocol;
>
> This __attribute__ is going to cause trouble on MSVC:
>
ok, I will use packed attribute.

>> +}__attribute__((aligned(4)));
>> +
>> +#define GRE_HEADER_SECTION 4
>> +
>
> It's pretty unusual for us to put htons() into value definitions:
ok I will fix it.

>> +#define GRE_CSUM        htons(0x8000)
>> +#define GRE_ROUTING     htons(0x4000)
>> +#define GRE_KEY         htons(0x2000)
>> +#define GRE_SEQ              htons(0x1000)
>> +#define GRE_STRICT      htons(0x0800)
>> +#define GRE_REC         htons(0x0700)
>> +#define GRE_FLAGS       htons(0x00F8)
>> +#define GRE_VERSION     htons(0x0007)
>
> Did you consider putting the GRE definitions into packets.h?
>
ok, I will move gre and vxlan header definitions to packets.h.

> I need to restart reading the code at netdev-vport.c.
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to