Hi,

I am asked to run a real-time networking application on a non real-time
network, so, I naturally thought about using RTnet.

But unless I am completely mistaken, it is not what RTnet is originally
made for. As far as I understood, in an RTnet network, the non real-time
trafic is tunneled through the real-time traffic by adding an rtmac
header with the RTMAC_FLAG_TUNNEL flag set. But since the other nodes on
the network I am on are non-rt, they do not understand the rtmac header.

So, I started hacking RTnet to get what I wanted, and since I believe it
may interest other users, I submit the patch here. I do not expect this
patch to be integrated as is, it is merely a one day hack, but it should
demonstrate my use-case of RTnet and hopefully influence RTnet
developers to take this use-case into account.

Regards.

-- 
                                                 Gilles Chanteperdrix
diff -x 'makefile*' -x .svn -x '*~' -x rtcfg.c -Naurdp rtnet-0.9.8/stack/include/ipv4/protocol.h rtnet/stack/include/ipv4/protocol.h
--- rtnet-0.9.8/stack/include/ipv4/protocol.h	2006-08-07 10:15:51.000000000 +0200
+++ rtnet/stack/include/ipv4/protocol.h	2007-03-14 18:58:44.000000000 +0100
@@ -40,7 +40,7 @@ struct rtinet_protocol {
     unsigned short      protocol;
 
     struct rtsocket     *(*dest_socket)(struct rtskb *);
-    void                (*rcv_handler)(struct rtskb *);
+    int                 (*rcv_handler)(struct rtskb *);
     void                (*err_handler)(struct rtskb *);
     int                 (*init_socket)(struct rtdm_dev_context *,
                                        rtdm_user_info_t *);
diff -x 'makefile*' -x .svn -x '*~' -x rtcfg.c -Naurdp rtnet-0.9.8/stack/include/rtmac/rtmac_proto.h rtnet/stack/include/rtmac/rtmac_proto.h
--- rtnet-0.9.8/stack/include/rtmac/rtmac_proto.h	2005-02-28 12:27:33.000000000 +0100
+++ rtnet/stack/include/rtmac/rtmac_proto.h	2007-03-15 12:05:52.000000000 +0100
@@ -34,17 +34,20 @@
 #define RTMAC_FLAG_TUNNEL       0x01
 
 
+#ifdef CONFIG_RTMAC_HDR
 struct rtmac_hdr {
     u16 type;
     u8  ver;
     u8  flags;
 } __attribute__ ((packed));
+#endif /* CONFIG_RTMAC_HDR */
 
 
 
 static inline int rtmac_add_header(struct rtnet_device *rtdev, void *daddr,
                                    struct rtskb *skb, u16 type, u8 flags)
 {
+#ifdef CONFIG_RTMAC_HDR
     struct rtmac_hdr *hdr =
         (struct rtmac_hdr *)rtskb_push(skb, sizeof(struct rtmac_hdr));
 
@@ -59,6 +62,14 @@ static inline int rtmac_add_header(struc
         (rtdev->hard_header(skb, rtdev, ETH_RTMAC, daddr,
                             rtdev->dev_addr, skb->len) < 0))
         return -1;
+#else
+    skb->rtdev = rtdev;
+
+    if (rtdev->hard_header &&
+        (rtdev->hard_header(skb, rtdev, type, daddr,
+                            rtdev->dev_addr, skb->len) < 0))
+        return -1;
+#endif
 
     return 0;
 }
@@ -81,7 +92,11 @@ static inline int rtmac_xmit(struct rtsk
 
 extern struct rtpacket_type rtmac_packet_type;
 
+#ifdef CONFIG_RTMAC_HDR
 #define rtmac_proto_init()  rtdev_add_pack(&rtmac_packet_type)
+#else
+int rtmac_proto_init(void);
+#endif
 void rtmac_proto_release(void);
 
 #endif /* __RTMAC_PROTO_H_ */
diff -x 'makefile*' -x .svn -x '*~' -x rtcfg.c -Naurdp rtnet-0.9.8/stack/ipv4/arp.c rtnet/stack/ipv4/arp.c
--- rtnet-0.9.8/stack/ipv4/arp.c	2006-09-15 13:25:01.000000000 +0200
+++ rtnet/stack/ipv4/arp.c	2007-03-15 11:19:31.000000000 +0100
@@ -168,14 +168,23 @@ int rt_arp_rcv(struct rtskb *skb, struct
     if (tip == rtdev->local_ip) {
         rt_ip_route_add_host(sip, sha, rtdev);
 
-        if (arp->ar_op == __constant_htons(ARPOP_REQUEST))
-            rt_arp_send(ARPOP_REPLY, ETH_P_ARP, sip, rtdev, tip, sha,
-                        rtdev->dev_addr, sha);
+        if (arp->ar_op == __constant_htons(ARPOP_REQUEST)) {
+		rt_arp_send(ARPOP_REPLY, ETH_P_ARP, sip, rtdev, tip, sha,
+			    rtdev->dev_addr, sha);
+#ifndef CONFIG_RTMAC_HDR
+		kfree_rtskb(skb);
+		return 0;
+#endif
+	}
     }
 
 out:
+#ifdef CONFIG_RTMAC_HDR
     kfree_rtskb(skb);
     return 0;
+#else
+    return 1;
+#endif
 }
 
 
diff -x 'makefile*' -x .svn -x '*~' -x rtcfg.c -Naurdp rtnet-0.9.8/stack/ipv4/icmp.c rtnet/stack/ipv4/icmp.c
--- rtnet-0.9.8/stack/ipv4/icmp.c	2006-09-04 19:15:15.000000000 +0200
+++ rtnet/stack/ipv4/icmp.c	2007-03-15 11:17:35.000000000 +0100
@@ -62,7 +62,7 @@ struct icmp_bxm
 
 struct rt_icmp_control
 {
-    void    (*handler)(struct rtskb *skb);
+    int    (*handler)(struct rtskb *skb);
     short   error;      /* This ICMP is classed as an error message */
 };
 
@@ -132,8 +132,14 @@ void rt_icmp_cleanup_echo_requests(void)
 /***
  *  rt_icmp_discard - dummy function
  */
-static void rt_icmp_discard(struct rtskb *skb)
+static int rt_icmp_discard(struct rtskb *skb)
 {
+#ifdef CONFIG_RTMAC_HDR
+	kfree_rtskb(skb);
+	return 0;
+#else
+        return 1;
+#endif
 }
 
 
@@ -200,7 +206,7 @@ static void rt_icmp_send_reply(struct ic
 /***
  *  rt_icmp_echo - handles echo replies on our previously sent requests
  */
-static void rt_icmp_echo_reply(struct rtskb *skb)
+static int rt_icmp_echo_reply(struct rtskb *skb)
 {
     rtdm_lockctx_t      context;
     struct rt_proc_call *call;
@@ -216,7 +222,12 @@ static void rt_icmp_echo_reply(struct rt
         rtdm_lock_put_irqrestore(&echo_calls_lock, context);
     } else {
         rtdm_lock_put_irqrestore(&echo_calls_lock, context);
-        return;
+#ifdef CONFIG_RTMAC_HDR
+	kfree_rtskb(skb);
+	return 0;
+#else
+        return 1;
+#endif
     }
 
     cmd = rtpc_get_priv(call, struct ipv4_cmd);
@@ -233,6 +244,13 @@ static void rt_icmp_echo_reply(struct rt
         rtpc_complete_call(call, sizeof(struct icmphdr) + skb->len);
     } else
         rtpc_complete_call(call, 0);
+
+#ifdef CONFIG_RTMAC_HDR
+    kfree_rtskb(skb);
+    return 0;
+#else
+    return 1;
+#endif
 }
 
 
@@ -240,7 +258,7 @@ static void rt_icmp_echo_reply(struct rt
 /***
  *  rt_icmp_echo_request - handles echo requests sent by other stations
  */
-static void rt_icmp_echo_request(struct rtskb *skb)
+static int rt_icmp_echo_request(struct rtskb *skb)
 {
     struct icmp_bxm icmp_param;
 
@@ -253,8 +271,9 @@ static void rt_icmp_echo_request(struct 
     icmp_param.head_len = sizeof(struct icmphdr);
 
     rt_icmp_send_reply(&icmp_param, skb);
+    kfree_rtskb(skb);
 
-    return;
+    return 0;
 }
 
 
@@ -439,7 +458,7 @@ struct rtsocket *rt_icmp_dest_socket(str
 /***
  *  rt_icmp_rcv
  */
-void rt_icmp_rcv(struct rtskb *skb)
+int rt_icmp_rcv(struct rtskb *skb)
 {
     struct icmphdr  *icmpHdr = skb->h.icmph;
     unsigned int    length   = skb->len;
@@ -472,10 +491,15 @@ void rt_icmp_rcv(struct rtskb *skb)
     }
 
     /* sane packet, process it */
-    rt_icmp_pointers[icmpHdr->type].handler(skb);
+    return rt_icmp_pointers[icmpHdr->type].handler(skb);
 
   cleanup:
+#ifdef CONFIG_RTMAC_HDR
     kfree_rtskb(skb);
+    return 0;
+#else
+    return 1;
+#endif
 }
 
 
diff -x 'makefile*' -x .svn -x '*~' -x rtcfg.c -Naurdp rtnet-0.9.8/stack/ipv4/ip_input.c rtnet/stack/ipv4/ip_input.c
--- rtnet-0.9.8/stack/ipv4/ip_input.c	2006-08-07 10:15:51.000000000 +0200
+++ rtnet/stack/ipv4/ip_input.c	2007-03-15 10:44:45.000000000 +0100
@@ -43,7 +43,7 @@ EXPORT_SYMBOL(rt_ip_fallback_handler);
 /***
  *  rt_ip_local_deliver
  */
-static inline void rt_ip_local_deliver(struct rtskb *skb)
+static inline int rt_ip_local_deliver(struct rtskb *skb)
 {
     struct iphdr *iph       = skb->nh.iph;
     unsigned short protocol = iph->protocol;
@@ -66,12 +66,15 @@ static inline void rt_ip_local_deliver(s
         if (iph->frag_off & htons(IP_MF|IP_OFFSET)) {
             skb = rt_ip_defrag(skb, ipprot);
             if (!skb)
-                return;
+                return 1;
         } else {
             /* Get the destination socket */
             if ((sock = ipprot->dest_socket(skb)) == NULL) {
+#ifdef CONFIG_RTMAC_HDR
                 kfree_rtskb(skb);
-                return;
+		return 0;
+#endif
+                return 1;
             }
 
             /* Acquire the rtskb at the expense of the protocol pool */
@@ -81,13 +84,16 @@ static inline void rt_ip_local_deliver(s
             rt_socket_dereference(sock);
 
             if (err) {
+#ifdef CONFIG_RTMAC_HDR
                 kfree_rtskb(skb);
-                return;
+		return 0;
+#endif
+                return 1;
             }
         }
 
         /* Deliver the packet to the next layer */
-        ipprot->rcv_handler(skb);
+	return ipprot->rcv_handler(skb);
 #ifdef CONFIG_RTNET_ADDON_PROXY
     } else if (rt_ip_fallback_handler) {
         /* If a fallback handler for IP protocol has been installed,
@@ -96,7 +102,11 @@ static inline void rt_ip_local_deliver(s
 #endif /* CONFIG_RTNET_ADDON_PROXY */
     } else {
         rtdm_printk("RTnet: no protocol found\n");
+#ifdef CONFIG_RTMAC_HDR
         kfree_rtskb(skb);
+	return 0;
+#endif
+	return 1;
     }
 }
 
@@ -145,8 +155,7 @@ int rt_ip_rcv(struct rtskb *skb, struct 
         return 0;
 #endif /* CONFIG_RTNET_RTIPV4_ROUTER */
 
-    rt_ip_local_deliver(skb);
-    return 0;
+    return rt_ip_local_deliver(skb);
 
   drop:
     kfree_rtskb(skb);
diff -x 'makefile*' -x .svn -x '*~' -x rtcfg.c -Naurdp rtnet-0.9.8/stack/ipv4/udp.c rtnet/stack/ipv4/udp.c
--- rtnet-0.9.8/stack/ipv4/udp.c	2006-12-11 17:29:52.000000000 +0100
+++ rtnet/stack/ipv4/udp.c	2007-03-14 19:01:30.000000000 +0100
@@ -723,7 +723,7 @@ struct rtsocket *rt_udp_dest_socket(stru
 /***
  *  rt_udp_rcv
  */
-void rt_udp_rcv (struct rtskb *skb)
+int rt_udp_rcv (struct rtskb *skb)
 {
     struct rtsocket *sock = skb->sk;
     void            (*callback_func)(struct rtdm_dev_context *, void *);
@@ -746,6 +746,7 @@ void rt_udp_rcv (struct rtskb *skb)
 
     if (callback_func)
         callback_func(rt_socket_context(sock), callback_arg);
+    return 0;
 }
 
 
diff -x 'makefile*' -x .svn -x '*~' -x rtcfg.c -Naurdp rtnet-0.9.8/stack/rtmac/rtmac_proto.c rtnet/stack/rtmac/rtmac_proto.c
--- rtnet-0.9.8/stack/rtmac/rtmac_proto.c	2006-09-15 13:27:24.000000000 +0200
+++ rtnet/stack/rtmac/rtmac_proto.c	2007-03-15 12:06:24.000000000 +0100
@@ -31,6 +31,7 @@
 
 
 
+#ifdef CONFIG_RTMAC_HDR
 int rtmac_proto_rx(struct rtskb *skb, struct rtpacket_type *pt)
 {
     struct rtmac_disc *disc = skb->rtdev->mac_disc;
@@ -82,3 +83,55 @@ void rtmac_proto_release(void)
         schedule_timeout(1*HZ); /* wait a second */
     }
 }
+#else /* !CONFIG_RTMAC_HDR */
+static int forward_to_vnic(struct rtskb *skb, struct rtpacket_type *pt)
+{
+	rtmac_vnic_rx(skb, skb->protocol);
+	return 0;
+}
+
+static struct rtpacket_type vnic_arp_packet_type = {
+	type:       __constant_htons(ETH_P_ARP),
+	handler:    forward_to_vnic
+};
+
+static struct rtpacket_type vnic_ip_packet_type = {
+	type:       __constant_htons(ETH_P_IP),
+	handler:    forward_to_vnic
+};
+
+int rtmac_proto_init(void)
+{
+	extern void rt_ip_init(void);
+	void *ptr = (void *) &rt_ip_init; /* Reference the rtipv4 module so that
+					   * it must be loaded before this one.*/
+	int rc = rtdev_add_pack(&vnic_arp_packet_type);
+	if (rc)
+		return rc;
+	
+	rc = rtdev_add_pack(&vnic_ip_packet_type);
+	if (rc) {
+		while (rtdev_remove_pack(&vnic_arp_packet_type) == -EAGAIN) {
+			rtdm_printk("RTmac: waiting for protocol unregistration\n");
+			set_current_state(TASK_UNINTERRUPTIBLE);
+			schedule_timeout(1*HZ); /* wait a second */
+		}
+	}
+		
+	return rc;
+}
+
+void rtmac_proto_release(void)
+{
+    while (rtdev_remove_pack(&vnic_arp_packet_type) == -EAGAIN) {
+        rtdm_printk("RTmac: waiting for protocol unregistration\n");
+        set_current_state(TASK_UNINTERRUPTIBLE);
+        schedule_timeout(1*HZ); /* wait a second */
+    }
+    while (rtdev_remove_pack(&vnic_ip_packet_type) == -EAGAIN) {
+        rtdm_printk("RTmac: waiting for protocol unregistration\n");
+        set_current_state(TASK_UNINTERRUPTIBLE);
+        schedule_timeout(1*HZ); /* wait a second */
+    }
+}
+#endif /* !CONFIG_RTMAC_HDR */
diff -x 'makefile*' -x .svn -x '*~' -x rtcfg.c -Naurdp rtnet-0.9.8/stack/rtmac/rtmac_vnic.c rtnet/stack/rtmac/rtmac_vnic.c
--- rtnet-0.9.8/stack/rtmac/rtmac_vnic.c	2006-08-07 10:15:51.000000000 +0200
+++ rtnet/stack/rtmac/rtmac_vnic.c	2007-03-15 11:54:14.000000000 +0100
@@ -93,6 +93,7 @@ static void rtmac_vnic_signal_handler(rt
 
             skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
 
+#ifdef CONFIG_RTMAC_HDR
             /* copy Ethernet header */
             memcpy(skb_put(skb, hdrlen),
                    rtskb->data - hdrlen - sizeof(struct rtmac_hdr), hdrlen);
@@ -102,6 +103,10 @@ static void rtmac_vnic_signal_handler(rt
 
             /* copy data */
             memcpy(skb_put(skb, rtskb->len), rtskb->data, rtskb->len);
+#else
+	    memcpy(skb_put(skb, hdrlen + rtskb->len),
+		   rtskb->data - hdrlen, hdrlen + rtskb->len);
+#endif
 
             skb->dev      = &rtskb->rtdev->mac_priv->vnic;
             skb->protocol = eth_type_trans(skb, skb->dev);
@@ -147,14 +152,23 @@ int rtmac_vnic_xmit(struct sk_buff *skb,
     int                     data_len;
 
 
+#ifdef CONFIG_RTMAC_HDR
     rtskb =
         alloc_rtskb((skb->len + sizeof(struct rtmac_hdr) + 15) & ~15, pool);
+#else
+    rtskb =
+        alloc_rtskb((skb->len + 15) & ~15, pool);
+#endif
     if (!rtskb) {
         stats->tx_dropped++;
         return -ENOMEM;
     }
 
+#ifdef CONFIG_RTMAC_HDR
     rtskb_reserve(rtskb, rtdev->hard_header_len + sizeof(struct rtmac_hdr));
+#else
+    rtskb_reserve(rtskb, rtdev->hard_header_len);
+#endif
 
     data_len = skb->len - dev->hard_header_len;
     memcpy(rtskb_put(rtskb, data_len), skb->data + dev->hard_header_len,
@@ -195,9 +209,14 @@ static struct net_device_stats *rtmac_vn
 
 static int rtmac_vnic_change_mtu(struct net_device *dev, int new_mtu)
 {
+#ifdef CONFIG_RTMAC_HDR
     if ((new_mtu < 68) ||
         ((unsigned)new_mtu > 1500 - sizeof(struct rtmac_hdr)))
         return -EINVAL;
+#else
+    if ((new_mtu < 68) || ((unsigned)new_mtu > 1500))
+        return -EINVAL;
+#endif
     dev->mtu = new_mtu;
     return 0;
 }
@@ -210,7 +229,11 @@ void rtmac_vnic_set_max_mtu(struct rtnet
     unsigned int        prev_mtu  = mac_priv->vnic_max_mtu;
 
 
+#ifdef CONFIG_RTMAC_HDR
     mac_priv->vnic_max_mtu = max_mtu - sizeof(struct rtmac_hdr);
+#else
+    mac_priv->vnic_max_mtu = max_mtu;
+#endif
 
     /* set vnic mtu in case max_mtu is smaller than the current mtu or
        the current mtu was set to previous max_mtu */
@@ -266,7 +289,11 @@ int rtmac_vnic_add(struct rtnet_device *
         return 0;
 
     mac_priv->vnic_registered = 0;
+#ifdef CONFIG_RTMAC_HDR
     mac_priv->vnic_max_mtu    = rtdev->mtu - sizeof(struct rtmac_hdr);
+#else
+    mac_priv->vnic_max_mtu    = rtdev->mtu;
+#endif
     memset(&mac_priv->vnic_stats, 0, sizeof(mac_priv->vnic_stats));
 
     /* create the rtskb pool */
diff -x 'makefile*' -x .svn -x '*~' -x rtcfg.c -Naurdp rtnet-0.9.8/stack/stack_mgr.c rtnet/stack/stack_mgr.c
--- rtnet-0.9.8/stack/stack_mgr.c	2006-09-15 16:10:18.000000000 +0200
+++ rtnet/stack/stack_mgr.c	2007-03-15 10:43:17.000000000 +0100
@@ -173,6 +173,10 @@ __DELIVER_PREFIX void rt_stack_deliver(s
 
     list_for_each_entry(pt_entry, &rt_packets[hash], list_entry)
         if (pt_entry->type == rtskb->protocol) {
+#ifndef CONFIG_RTMAC_HDR
+	    unsigned char *data = rtskb->data;
+	    unsigned len = rtskb->len;
+#endif
             pt_entry->refcount++;
             rtdm_lock_put_irqrestore(&rt_packets_lock, context);
 
@@ -187,6 +191,12 @@ __DELIVER_PREFIX void rt_stack_deliver(s
                 rtdm_lock_put_irqrestore(&rt_packets_lock, context);
                 return;
             }
+#ifndef CONFIG_RTMAC_HDR
+	    /* Discard any progress made by the last callback before passing the
+	       packet to the next callback. */
+	    rtskb->data = data;
+	    rtskb->len = len;
+#endif
         }
 
     rtdm_lock_put_irqrestore(&rt_packets_lock, context);
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
RTnet-developers mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/rtnet-developers

Reply via email to