net: hsr: define and use proto_ops ptrs to handle hsr specific frames
authorMurali Karicheri <m-karicheri2@ti.com>
Wed, 22 Jul 2020 14:40:20 +0000 (10:40 -0400)
committerDavid S. Miller <davem@davemloft.net>
Mon, 27 Jul 2020 19:20:40 +0000 (12:20 -0700)
As a preparatory patch to introduce PRP, refactor the code specific to
handling HSR frames into separate functions and call them through
proto_ops function pointers.

Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/hsr/hsr_device.c
net/hsr/hsr_forward.c
net/hsr/hsr_forward.h
net/hsr/hsr_main.h

index 74eaf28..022393b 100644 (file)
@@ -440,9 +440,12 @@ static struct device_type hsr_type = {
 
 static struct hsr_proto_ops hsr_ops = {
        .send_sv_frame = send_hsr_supervision_frame,
+       .create_tagged_frame = hsr_create_tagged_frame,
+       .get_untagged_frame = hsr_get_untagged_frame,
+       .fill_frame_info = hsr_fill_frame_info,
 };
 
-struct hsr_proto_ops prp_ops = {
+static struct hsr_proto_ops prp_ops = {
        .send_sv_frame = send_prp_supervision_frame,
 };
 
index dedf8ac..33e8136 100644 (file)
@@ -116,8 +116,8 @@ static struct sk_buff *create_stripped_skb(struct sk_buff *skb_in,
        return skb;
 }
 
-static struct sk_buff *frame_get_stripped_skb(struct hsr_frame_info *frame,
-                                             struct hsr_port *port)
+struct sk_buff *hsr_get_untagged_frame(struct hsr_frame_info *frame,
+                                      struct hsr_port *port)
 {
        if (!frame->skb_std)
                frame->skb_std = create_stripped_skb(frame->skb_hsr, frame);
@@ -192,8 +192,8 @@ static struct sk_buff *create_tagged_skb(struct sk_buff *skb_o,
 /* If the original frame was an HSR tagged frame, just clone it to be sent
  * unchanged. Otherwise, create a private frame especially tagged for 'port'.
  */
-static struct sk_buff *frame_get_tagged_skb(struct hsr_frame_info *frame,
-                                           struct hsr_port *port)
+struct sk_buff *hsr_create_tagged_frame(struct hsr_frame_info *frame,
+                                       struct hsr_port *port)
 {
        if (frame->skb_hsr)
                return skb_clone(frame->skb_hsr, GFP_ATOMIC);
@@ -257,6 +257,7 @@ static void hsr_forward_do(struct hsr_frame_info *frame)
        struct sk_buff *skb;
 
        hsr_for_each_port(frame->port_rcv->hsr, port) {
+               struct hsr_priv *hsr = port->hsr;
                /* Don't send frame back the way it came */
                if (port == frame->port_rcv)
                        continue;
@@ -282,9 +283,10 @@ static void hsr_forward_do(struct hsr_frame_info *frame)
                }
 
                if (port->type != HSR_PT_MASTER)
-                       skb = frame_get_tagged_skb(frame, port);
+                       skb = hsr->proto_ops->create_tagged_frame(frame, port);
                else
-                       skb = frame_get_stripped_skb(frame, port);
+                       skb = hsr->proto_ops->get_untagged_frame(frame, port);
+
                if (!skb) {
                        /* FIXME: Record the dropped frame? */
                        continue;
@@ -317,12 +319,34 @@ static void check_local_dest(struct hsr_priv *hsr, struct sk_buff *skb,
        }
 }
 
-static int hsr_fill_frame_info(struct hsr_frame_info *frame,
-                              struct sk_buff *skb, struct hsr_port *port)
+void hsr_fill_frame_info(__be16 proto, struct sk_buff *skb,
+                        struct hsr_frame_info *frame)
 {
-       struct ethhdr *ethhdr;
+       struct hsr_priv *hsr = frame->port_rcv->hsr;
        unsigned long irqflags;
 
+       if (proto == htons(ETH_P_PRP) || proto == htons(ETH_P_HSR)) {
+               frame->skb_std = NULL;
+               frame->skb_hsr = skb;
+               frame->sequence_nr = hsr_get_skb_sequence_nr(skb);
+       } else {
+               frame->skb_std = skb;
+               frame->skb_hsr = NULL;
+               /* Sequence nr for the master node */
+               spin_lock_irqsave(&hsr->seqnr_lock, irqflags);
+               frame->sequence_nr = hsr->sequence_nr;
+               hsr->sequence_nr++;
+               spin_unlock_irqrestore(&hsr->seqnr_lock, irqflags);
+       }
+}
+
+static int fill_frame_info(struct hsr_frame_info *frame,
+                          struct sk_buff *skb, struct hsr_port *port)
+{
+       struct hsr_priv *hsr = port->hsr;
+       struct ethhdr *ethhdr;
+       __be16 proto;
+
        frame->is_supervision = is_supervision_frame(port->hsr, skb);
        frame->node_src = hsr_get_node(port, skb, frame->is_supervision);
        if (!frame->node_src)
@@ -335,23 +359,10 @@ static int hsr_fill_frame_info(struct hsr_frame_info *frame,
                /* FIXME: */
                netdev_warn_once(skb->dev, "VLAN not yet supported");
        }
-       if (ethhdr->h_proto == htons(ETH_P_PRP) ||
-           ethhdr->h_proto == htons(ETH_P_HSR)) {
-               frame->skb_std = NULL;
-               frame->skb_hsr = skb;
-               frame->sequence_nr = hsr_get_skb_sequence_nr(skb);
-       } else {
-               frame->skb_std = skb;
-               frame->skb_hsr = NULL;
-               /* Sequence nr for the master node */
-               spin_lock_irqsave(&port->hsr->seqnr_lock, irqflags);
-               frame->sequence_nr = port->hsr->sequence_nr;
-               port->hsr->sequence_nr++;
-               spin_unlock_irqrestore(&port->hsr->seqnr_lock, irqflags);
-       }
-
+       proto = ethhdr->h_proto;
        frame->port_rcv = port;
-       check_local_dest(port->hsr, skb, frame);
+       hsr->proto_ops->fill_frame_info(proto, skb, frame);
+       check_local_dest(hsr, skb, frame);
 
        return 0;
 }
@@ -367,7 +378,7 @@ void hsr_forward_skb(struct sk_buff *skb, struct hsr_port *port)
                goto out_drop;
        }
 
-       if (hsr_fill_frame_info(&frame, skb, port) < 0)
+       if (fill_frame_info(&frame, skb, port) < 0)
                goto out_drop;
        hsr_register_frame_in(frame.node_src, port, frame.sequence_nr);
        hsr_forward_do(&frame);
index b2a6fa3..8932077 100644 (file)
 #include "hsr_main.h"
 
 void hsr_forward_skb(struct sk_buff *skb, struct hsr_port *port);
-
+struct sk_buff *hsr_create_tagged_frame(struct hsr_frame_info *frame,
+                                       struct hsr_port *port);
+struct sk_buff *hsr_get_untagged_frame(struct hsr_frame_info *frame,
+                                      struct hsr_port *port);
+void hsr_fill_frame_info(__be16 proto, struct sk_buff *skb,
+                        struct hsr_frame_info *frame);
 #endif /* __HSR_FORWARD_H */
index 58e1ad2..14f442c 100644 (file)
@@ -162,9 +162,17 @@ enum hsr_version {
        PRP_V1,
 };
 
+struct hsr_frame_info;
+
 struct hsr_proto_ops {
        /* format and send supervision frame */
        void (*send_sv_frame)(struct hsr_port *port, unsigned long *interval);
+       struct sk_buff * (*get_untagged_frame)(struct hsr_frame_info *frame,
+                                              struct hsr_port *port);
+       struct sk_buff * (*create_tagged_frame)(struct hsr_frame_info *frame,
+                                               struct hsr_port *port);
+       void (*fill_frame_info)(__be16 proto, struct sk_buff *skb,
+                               struct hsr_frame_info *frame);
 };
 
 struct hsr_priv {