Re: [iproute PATCH] Add ip rule save/restore

2015-10-23 Thread Stephen Hemminger
On Tue, 20 Oct 2015 13:41:48 +0300
Kirill Tkhai  wrote:

> This patch adds save and restore commands to "ip rule"
> similar the same is made in commit f4ff11e3e298 for "ip route".
> 
> The feature is useful in checkpoint/restore for container
> migration, also it may be helpful in some normal situations.
> 
> Signed-off-by: Kirill Tkhai 

Sure applied.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[iproute PATCH] Add ip rule save/restore

2015-10-20 Thread Kirill Tkhai
This patch adds save and restore commands to "ip rule"
similar the same is made in commit f4ff11e3e298 for "ip route".

The feature is useful in checkpoint/restore for container
migration, also it may be helpful in some normal situations.

Signed-off-by: Kirill Tkhai 
---
 doc/ip-cref.tex|   36 ++
 ip/iprule.c|  103 +---
 man/man8/ip-rule.8 |   26 +
 3 files changed, 158 insertions(+), 7 deletions(-)

diff --git a/doc/ip-cref.tex b/doc/ip-cref.tex
index ea14795..67094c9 100644
--- a/doc/ip-cref.tex
+++ b/doc/ip-cref.tex
@@ -2246,6 +2246,42 @@ Besides that, the host 193.233.7.83 is translated into
 another prefix to look like 192.203.80.144 when talking
 to the outer world.
 
+\subsection{{\tt ip rule save} -- save rules tables}
+\label{IP-RULE-SAVE}
+
+\paragraph{Description:} this command saves the contents of the rules
+tables or the rule(s) selected by some criteria to standard output.
+
+\paragraph{Arguments:} \verb|ip rule save| has the same arguments as
+\verb|ip rule show|.
+
+\paragraph{Example:} This saves all the rules to the {\tt saved\_rules}
+file:
+\begin{verbatim}
+dan@caffeine:~ # ip rule save > saved_rules
+\end{verbatim}
+
+\paragraph{Output format:} The format of the data stream provided by
+\verb|ip rule save| is that of \verb|rtnetlink|.  See
+\verb|rtnetlink(7)| for more information.
+
+\subsection{{\tt ip rule restore} -- restore rules tables}
+\label{IP-RULE-RESTORE}
+
+\paragraph{Description:} this command restores the contents of the rules
+tables according to a data stream as provided by \verb|ip rule save| via
+standard input.  Note that any rules already in the table are left unchanged,
+and duplicates are not ignored.
+
+\paragraph{Arguments:} This command takes no arguments.
+
+\paragraph{Example:} This restores all rules that were saved to the
+{\tt saved\_rules} file:
+
+\begin{verbatim}
+dan@caffeine:~ # ip rule restore < saved_rules
+\end{verbatim}
+
 
 
 \section{{\tt ip maddress} --- multicast addresses management}
diff --git a/ip/iprule.c b/ip/iprule.c
index 2fa9ade..cec2924 100644
--- a/ip/iprule.c
+++ b/ip/iprule.c
@@ -21,6 +21,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "rt_names.h"
 #include "utils.h"
@@ -32,7 +33,8 @@ static void usage(void) __attribute__((noreturn));
 
 static void usage(void)
 {
-   fprintf(stderr, "Usage: ip rule [ list | add | del | flush ] SELECTOR 
ACTION\n");
+   fprintf(stderr, "Usage: ip rule [ list | add | del | flush | save ] 
SELECTOR ACTION\n");
+   fprintf(stderr, "   ip rule restore\n");
fprintf(stderr, "SELECTOR := [ not ] [ from PREFIX ] [ to PREFIX ] [ 
tos TOS ] [ fwmark FWMARK[/MASK] ]\n");
fprintf(stderr, "[ iif STRING ] [ oif STRING ] [ pref 
NUMBER ]\n");
fprintf(stderr, "ACTION := [ table TABLE_ID ]\n");
@@ -205,24 +207,65 @@ int print_rule(const struct sockaddr_nl *who, struct 
nlmsghdr *n, void *arg)
return 0;
 }
 
-static int iprule_list(int argc, char **argv)
+static __u32 rule_dump_magic = 0x71706986;
+
+static int save_rule_prep(void)
+{
+   int ret;
+
+   if (isatty(STDOUT_FILENO)) {
+   fprintf(stderr, "Not sending a binary stream to stdout\n");
+   return -1;
+   }
+
+   ret = write(STDOUT_FILENO, _dump_magic, sizeof(rule_dump_magic));
+   if (ret != sizeof(rule_dump_magic)) {
+   fprintf(stderr, "Can't write magic to dump file\n");
+   return -1;
+   }
+
+   return 0;
+}
+
+static int save_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void 
*arg)
 {
+   int ret;
+
+   ret = write(STDOUT_FILENO, n, n->nlmsg_len);
+   if ((ret > 0) && (ret != n->nlmsg_len)) {
+   fprintf(stderr, "Short write while saving nlmsg\n");
+   ret = -EIO;
+   }
+
+   return ret == n->nlmsg_len ? 0 : ret;
+}
+
+static int iprule_list_or_save(int argc, char **argv, int save)
+{
+   rtnl_filter_t filter = print_rule;
int af = preferred_family;
 
if (af == AF_UNSPEC)
af = AF_INET;
 
if (argc > 0) {
-   fprintf(stderr, "\"ip rule show\" does not take any 
arguments.\n");
+   fprintf(stderr, "\"ip rule %s\" does not take any arguments.\n",
+   save ? "save" : "show");
return -1;
}
 
+   if (save) {
+   if (save_rule_prep())
+   return -1;
+   filter = save_rule;
+   }
+
if (rtnl_wilddump_request(, af, RTM_GETRULE) < 0) {
perror("Cannot send dump request");
return 1;
}
 
-   if (rtnl_dump_filter(, print_rule, stdout) < 0) {
+   if (rtnl_dump_filter(, filter, stdout) < 0) {
fprintf(stderr, "Dump terminated\n");
return 1;
}
@@ -230,6 +273,50 @@ static int iprule_list(int argc,